目录
[C++ 完整代码](#C++ 完整代码)
[四、解法二:广度优先搜索(BFS 层序遍历)](#四、解法二:广度优先搜索(BFS 层序遍历))
[C++ 完整代码](#C++ 完整代码)
[五、解法三:迭代 DFS(栈模拟递归)](#五、解法三:迭代 DFS(栈模拟递归))
[C++ 完整代码](#C++ 完整代码)
给定一棵二叉树的根节点 root,要求返回该二叉树的最大深度。
核心定义:二叉树最大深度指从根节点到最远叶子节点的最长路径上的节点数量。
- 叶子节点:左右子节点均为空的节点
- 空二叉树:深度为 0
- 单节点二叉树:深度为 1
示例
plaintext
输入:root = [3,9,20,null,null,15,7]
输出:3
解释:最长路径:3 → 20 → 15 / 3 → 20 →7,共3层
二、解题思路总览
二叉树经典入门题,也是面试高频基础题,主流三种解法:
- 递归 DFS:代码极简,分治思想,最容易理解
- 迭代 BFS:层序遍历,按层计数,天然对应深度
- 迭代 DFS:栈模拟递归,避免栈溢出,适合大数场景
三、解法一:递归深度优先搜索(DFS)
思路分析
基于二叉树天然的递归结构,采用后序遍历 + 分治思想:
- 递归终止条件:当前节点为空,深度直接返回 0
- 递归计算左子树最大深度、右子树最大深度
- 当前节点深度 = 左右子树深度最大值 + 1(加上自身节点)
简单理解:一棵树的高度 = 左右两棵子树更高的那一棵 + 根节点。
C++ 完整代码
cpp
运行
// 二叉树节点定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
// 空节点,深度为0
if (root == nullptr) return 0;
// 递归计算左右子树深度
int leftDep = maxDepth(root->left);
int rightDep = maxDepth(root->right);
// 当前层深度 = 子树最大值 + 1
return max(leftDep, rightDep) + 1;
}
};
复杂度分析
- 时间复杂度:O(n),n 为节点总数,每个节点仅遍历一次
- 空间复杂度:O(h),h 为树的高度,递归栈占用空间;最坏情况(斜树)O(n),平衡二叉树 O(logn)
优缺点
✅ 代码简洁、逻辑清晰、上手最快❌ 极端倾斜二叉树会出现递归栈溢出问题
四、解法二:广度优先搜索(BFS 层序遍历)
思路分析
BFS 按层级遍历二叉树,层数就是二叉树的最大深度:
- 借助队列存储每一层的节点
- 每次遍历前获取队列长度,即当前层所有节点数量
- 逐层遍历,弹出当前层节点,并入队其左右子节点
- 每遍历完一层,深度计数器 +1
C++ 完整代码
cpp
运行
#include <queue>
using namespace std;
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
while (!q.empty()) {
// 当前层节点数量
int size = q.size();
// 遍历当前层所有节点
for (int i = 0; i < size; ++i) {
TreeNode* cur = q.front();
q.pop();
// 子节点入队
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
}
// 层数+1
depth++;
}
return depth;
}
};
复杂度分析
- 时间复杂度:O(n),所有节点入队出队各一次
- 空间复杂度:O(n),最坏情况下队列存储整棵树节点(完全二叉树最后一层)
优缺点
✅ 无递归栈溢出风险,直观理解深度层级关系❌ 额外需要队列空间,代码比递归稍长
五、解法三:迭代 DFS(栈模拟递归)
思路分析
手动创建栈模拟递归过程,存储 节点 + 当前深度:
- 根节点和初始深度 1 入栈
- 不断弹出栈顶元素,更新全局最大深度
- 右节点先入栈、左节点后入栈(保证遍历顺序和递归一致)
C++ 完整代码
cpp
运行
#include <stack>
using namespace std;
// 栈存储节点与对应深度
struct NodeDepth {
TreeNode* node;
int depth;
};
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
stack<NodeDepth> stk;
stk.push({root, 1});
int maxDep = 0;
while (!stk.empty()) {
auto cur = stk.top();
stk.pop();
maxDep = max(maxDep, cur.depth);
// 右子树先入栈,左子树后入栈
if (cur.node->right) stk.push({cur.node->right, cur.depth + 1});
if (cur.node->left) stk.push({cur.node->left, cur.depth + 1});
}
return maxDep;
}
};
六、三种解法对比与选择建议
表格
| 解法 | 核心方式 | 适用场景 |
|---|---|---|
| 递归 DFS | 分治、代码最短 | 日常刷题、数据量小、快速解题 |
| BFS 层序 | 层级遍历、计数深度 | 防止栈溢出、理解二叉树层级 |
| 迭代 DFS | 栈模拟递归 | 大数据量、工程开发避免递归隐患 |
七、总结
- 二叉树深度问题核心公式:
当前深度 = 子树最大深度 + 1,是二叉树递归题的通用思想。 - 刷题优先使用递归 DFS,一行核心代码即可解决;面试需要主动说出迭代解法,体现思维全面性。
- 递归与迭代互为补充:递归简洁易写,迭代稳定安全,根据场景灵活切换。