二叉树的层序遍历
671 字
3 分钟
二叉树的层序遍历
题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode)
- 难度:🟡 中等
- 标签:树、广度优先搜索、二叉树、队列
题目描述
Note
原题说明:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1
graph TD
3((3)) --- 9((9))
3((3)) --- 20((20))
20((20)) --- 15((15))
20((20)) --- 7((7))
style 15 fill:#d1e8ff,stroke:#333,stroke-width:2px
style 7 fill:#d1e8ff,stroke:#333,stroke-width:2px
输出:[[3], [9, 20], [15, 7]]
方案:广度优先搜索 (BFS)
核心思路: 层序遍历是典型的广度优先搜索(BFS)应用。为了能够区分不同的层,我们需要在每一层开始处理前,记录下当前队列中节点的数量。
- 初始化:根节点入队。
- 层级循环:只要队列不为空,就说明还有层没跑完。
- 节点循环:记录当前队列的大小
sz,表示这一层有多少个节点。 - 出队与入队:循环
sz次,弹出节点并记录值,同时将其左右子节点(如果有)送入队列末尾排队。
源码实现
#include <queue>#include <vector>
class Solution {public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> ans; if (!root) return ans;
queue<TreeNode*> q; q.push(root);
while (!q.empty()) { // 关键:在进入本层循环前,记录当前队列长度 int sz = q.size(); vector<int> curLevel;
// 严格出队 sz 个节点,这些节点恰好属于同一层 for (int i = 0; i < sz; ++i) { TreeNode* node = q.front(); q.pop(); curLevel.push_back(node->val);
// 将下一层节点加入队尾(此时不会在当前 for 循环中被处理) if (node->left) q.push(node->left); if (node->right) q.push(node->right); } // 使用 move 避免不必要的 vector 拷贝 ans.push_back(move(curLevel)); } return ans; }};复杂度分析
- 时间复杂度:。每个节点入队和出队各一次。
- 空间复杂度:。在最坏情况下(完全二叉树),队列中最多存储一层节点,即 个节点。
避坑指南:为什么需要 sz = q.size()?
Important
常见误区:
如果直接在 for 循环中使用 i < q.size(),由于循环体内会不断向队列 push 下一层的节点,会导致 q.size() 实时变大,从而导致单次循环无法准确收割“当前层”的所有节点。
解决办法:在 for 循环之前快照当下的 size。
总结
- BFS 的灵魂:队列(Queue)是实现 BFS 的核心数据结构。
- 层级区分:快照
size技巧是层序遍历中处理vector<vector<int>>的金标准。 - 内存优化:使用
std::move可以有效提升二维容器填充时的效率。
Tip
掌握了 BFS 的这个“套路”,不仅能解二叉树层序遍历,连图论里的最短路径、网络流量等复杂问题也都能迎刃而解!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2025-11-07,距今已过 173 天
部分内容可能已过时
相关文章 智能推荐
1
二叉树的层序遍历 II
算法 力扣第107题:二叉树的层序遍历 II。在层序遍历的基础上,学习如何通过简单的结果反转实现自底向上的层级展示。
2
二叉树的中序遍历
算法 力扣第94题:二叉树的中序遍历。从递归的简洁到迭代的深度剖析,掌握树结构遍历的核心逻辑。
3
二叉树的最大深度
算法 力扣第104题:二叉树的最大深度。深入理解递归与广度优先搜索(BFS)在计算树结构深度时的应用场景。
4
对称二叉树
算法 力扣第101题:对称二叉树。深入理解树的镜像对称性质,掌握递归与迭代两种姿势下的双向比对技巧。
5
相同的树
算法 力扣第100题:相同的树。利用深度优先搜索(DFS)的递归特性,优雅地判断两棵二叉树的结构与数值一致性。
随机文章 随机推荐