层序遍历必须用队列,因其本质是广度优先搜索(bfs),需严格按层从上到下、从左到右访问节点,天然契合队列“先进先出”(fifo)特性;递归或栈会破坏层级顺序,导致深度优先行为或崩溃。

用队列实现二叉树的层序遍历,本质就是模拟广度优先搜索(BFS)的过程:一层一层推进,每层从左到右访问节点。关键不在于队列多复杂,而在于怎么用好“先进先出”这个特性。
为什么必须用队列
因为层序遍历要求先访问上层所有节点,再处理下一层——这天然匹配队列的 FIFO 行为。如果用栈,就会变成深度优先;用数组或链表手动管理顺序,容易错位或漏节点。队列让逻辑清晰、不易出错。
基础版:平铺输出(一行一个值)
适合调试或简单打印。核心三步循环:
- 根节点入队(前提是不为空)
- 队列非空时,取队首节点 → 访问它的值 → 把它的左、右子节点(若存在)依次入队
- 重复第二步,直到队列为空
这个过程天然保证了访问顺序是 1→2→3→4→5→6…(按层+从左到右)。
进阶版:分层存储(每层一个列表)
LeetCode 102 这类题要求返回 List>
,就得在每次循环开始前记录当前队列长度:size。
- 每次外层 while 循环中,先获取 queue.size(),这就是当前层的节点数
- 内层 for 循环执行 size 次,每次 poll 一个节点,加入当前层列表,并把它的孩子入队
- 本轮 for 结束后,当前层列表 add 进结果集合
这样就能严格区分第 1 层、第 2 层……避免混在一起。
实际编码注意点
写代码时容易忽略但影响正确性的细节:
- 判空必须放在最前:root == null 直接返回空结果,否则后续操作会空指针
- 左右子节点入队前一定要判非空,否则可能往队列塞 null,导致后续 poll 出 null 后调用 .val 报错
- Java 中推荐用 LinkedList
或 ArrayDeque ,后者性能略优;C++ 可用 std::queue;C 语言需手写链式队列结构











