【深基16.例3】二叉树深度(洛谷P4913)

题目描述

有一个 n(n≤10^6) 个结点的二叉树。给出每个结点的两个子结点编号(均不超过 n),建立一棵二叉树(根节点的编号为 1),如果是叶子结点,则输入 0 0

建好这棵二叉树之后,请求出它的深度。二叉树的深度是指从根节点到叶子结点时,最多经过了几层。

输入格式

第一行一个整数 n,表示结点数。

之后 n 行,第 i 行两个整数 l、r,分别表示结点 i 的左右子结点编号。若 l=0 则表示无左子结点,r=0 同理。

输出格式

一个整数,表示最大结点深度。

输入输出样例

输入 #1复制

复制代码
7
2 7
3 6
4 5
0 0
0 0
0 0
0 0

输出 #1复制

复制代码
4

问题分析与核心思路

本题要求计算给定二叉树的最大深度 。我们采用广度优先搜索 (BFS) 来解决,因为它天然地按层级遍历。

  1. BFS 特性: 保证先访问层级低的节点,后访问层级高的节点。

  2. 深度计算: 在遍历过程中,利用父节点的深度信息,推算出子节点的深度(父节点深度+ 1)。

  3. 最终答案: 所有节点中记录的最大层级值即为树的最大深度。

📊 数据结构设计

为了存储树结构和节点深度,我们定义了结构体 node

cpp 复制代码
struct node{
    int l;//左儿子
    int r;//右儿子
    int level;//节点所在层级/深度
}a[1000001];
  • a 数组存储所有节点信息。

  • queue<node> q 用于辅助 BFS 遍历。

  • ma 记录当前已知的最大深度。

BFS 算法实现 (bfs 函数)

bfs 函数实现了核心的层序遍历逻辑。

1. 初始化

将根节点(编号 1)入队,并假设其深度已初始化为 1。

2. 循环遍历

使用 while(!q.empty()) 进行循环。

  1. 出队访问:

    cpp 复制代码
    node tmp=q.front();
    q.pop();
  2. 处理左儿子:

    cpp 复制代码
    if(tmp.l!=0){ // 检查左儿子是否存在
        // 关键:a[i].level == 0 标记节点是否已访问
        if(a[tmp.l].level==0){ 
            a[tmp.l].level=tmp.level+1; // 新深度 = 父节点深度 + 1
            q.push(a[tmp.l]);           // 左儿子入队
            ma=max(ma,a[tmp.l].level); // 更新最大深度
        }
    }
  3. 处理右儿子:

    处理逻辑与左儿子相同,确保右儿子也入队并更新最大深度。

3. 结果输出

遍历完成后,输出 ma

完整代码流程

main 函数中,我们负责读取数据、初始化根节点深度,并调用 BFS 函数。

cpp 复制代码
//洛谷P4913 【深基16.例3】二叉树深度
#include <iostream>
#include <queue>
using namespace std;

struct node{
    int l;//左儿子
    int r;//右儿子
    int level;//节点所在层次
}a[1000001];
int ma=0;
queue<node> q;
void bfs(int root){//根节点传进来
    node tmp;
    tmp=a[root];
    q.push(tmp);//根节点入队
    while(!q.empty()){
        tmp=q.front();//访问队首元素
        q.pop();//队首出队
        //得有左儿子
        if(tmp.l!=0) {
            //左儿子没有走过
            if(a[tmp.l].level==0){
                a[tmp.l].level=tmp.level+1;
                q.push(a[tmp.l]);//没有访问过就入队
                ma=max(ma,a[tmp.l].level);
            }
            
        }
        //得有右儿子
        if(tmp.r!=0){
            //右儿子没有走过
            if(a[tmp.r].level==0){
                a[tmp.r].level=tmp.level+1;
                q.push(a[tmp.r]);
                ma=max(ma,a[tmp.r].level);
            }
            
        }
    }
    cout<<ma;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].l>>a[i].r;
    a[1].level=1;
    ma=1;
    bfs(1);
    return 0;
}
相关推荐
白狐_7981 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2582 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记2 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI2 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型3 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光3 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院4 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡5 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
杨石兴5 小时前
31、玩具MoM:用2x2矩阵串起全套流程
人工智能·算法·矩阵·电磁学
江畔柳前堤5 小时前
Function Calling 与 Tool Calling:从认知到工程的全景深度解析
开发语言·网络·人工智能·深度学习·算法·机器学习·php