跳到正文
第 102 题中等

二叉树的层序遍历

Binary Tree Level Order Traversal

给你一棵二叉树,按「从上到下、从左到右」的层次顺序,把每一层的节点值收集成一个数组返回。

在力扣中练习

题目描述

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

 

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

 

提示:

  • 树中节点数目在范围 [0, 2000] 内
  • -1000 <= Node.val <= 1000

解题思路

主解法

BFS · 队列分层

队列 + 每层开始前锁住 size

深度优先会先走完一条分支,层序遍历则要求同层从左到右。队列的先进先出能保证顺序,但还需要明确每一层在哪里结束。

自拟主例 root = [8,4,12,null,6,10,15] 返回 [[8],[4,12],[6,10,15]]。4 缺少左孩子,6 是它的右孩子,图中保留这个空位。

分步图解

锁定本层 sz=1;这轮只取出这 1 个节点。

sz
1
二叉树 · 空位保留左右关系左子树 · 右子树
841261015
队列 q先进先出
← 队首出队队尾入队 ←
8front
本层剩余 1下一层 0
res
[ ]
1 / 4
只消费本轮锁定的节点数,新孩子留给下一层。

每轮开始先锁定 sz = q.size(),接下来只取这 sz 个节点。处理时把孩子追加到队尾,它们属于下一层,不能改变当前循环次数。

分步图解

本层结束,把 [8] 收进 res;队列中全是下一层。

二叉树 · 空位保留左右关系左子树 · 右子树
841261015
队列 q先进先出
← 队首出队队尾入队 ←
4front
12rear
本层剩余 0下一层 2
res
[8]
1 / 3
res 每次追加完整一层,而不是每处理一个节点就追加一层。

本轮的 level 填完后整体追加到 res,再进入下一轮。若把不断变化的 q.size() 直接写进循环条件,同一层可能被提前截断或与下一层混合。空树不入队,结果自然为空。

时间 O(n)空间 O(n)

易错点

  • 把 sz 写成 q.size() 直接放进 for 条件里:队列在循环中会变长,循环次数就错了。
  • 忘记处理空树,root 为空时访问 root->val 直接崩溃。
  • 用 vector 当队列并频繁 erase(begin()),复杂度退化到 O(n²)。
对照解法

DFS · 按深度归档

递归时带上 depth,把节点塞进对应层

同样是 O(n) 的正确做法,适合对照递归与按深度归档;主图解使用队列 BFS。

层序不一定非要用 BFS。带着深度递归下去,把节点放进 res[depth] 也行:

  • 第一次到达某个深度时,res.size() == depth,说明这一层还没建过,先 push_back({}) 开一个新层;
  • 然后把节点值追加到 res[depth]。

因为递归是「先左后右」,同一层内的左右顺序自然就是从左到右,结果和 BFS 完全一致。

需要注意递归的访问顺序:先序遍历保证每个节点都在正确的深度被访问,且同层顺序正确。

这个写法在「二叉树的右视图」(199)里特别好用:res[depth] = node->val 覆盖写入,最后留下的就是每层最右边的节点。

  1. 1从根节点开始,depth = 0。
  2. 2若 depth == res.size(),为这一层新建一个空数组。
  3. 3把当前值追加到 res[depth]。
  4. 4递归左右孩子,depth + 1。
时间 O(n)空间 O(h)(递归栈)

易错点

  • 先递归再判断 depth,会导致空层被跳过。
  • 用 res[depth] 直接访问而没有先扩容,会越界。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入root = [8,4,12,null,6,10,15]

建立结果数组和空队列;空树直接返回。

二叉树 · 空位保留左右关系左子树 · 右子树
841261015
队列 q先进先出
← 队首出队队尾入队 ←
空队列
本层剩余 0下一层 0
res
[ ]
1 / 15
查看 C++ 代码

延伸阅读

  • 「锁住当前队列长度」是 BFS 分层的通用模板,也适用于:二叉树的右视图(199)、每层最大值、之字形遍历(103)。
  • 需要记录「第几层」时,BFS 用 sz 分组,DFS 用 depth 归档——两条路都能到。
  • 图的 BFS(如腐烂的橘子 994)同理,只是「层」变成了「时间步」。