用queue实现bfs层序遍历的核心是每次外层循环前记录q.size()作为当前层节点数,内层循环执行该次数并逐个处理;入队前必须检查子节点非空,根为空时直接跳过;每层结果用独立vector存储,避免clear()引发的问题。

用 queue 实现 BFS 层序遍历,核心是记录每层节点数
直接用 std::queue 做 BFS 没问题,但“分层”意味着每次循环处理完一层所有节点,而不是混在一起输出。关键不是靠节点值判断边界,而是靠队列在进入内层循环前的大小——它精确等于当前层的节点数量。
- 每次外层循环开始前,先读取
q.size(),记为level_size - 内层循环执行
level_size次,每次pop()一个节点,并将它的左右子节点(若非空)push()入队 - 这样每轮外层循环对应一层,内层循环天然隔离层级
TreeNode 结构和空指针检查必须显式处理
很多人写到 q.push(root->left) 就报错,是因为没判空。C++ 不像 Python 有可选链式调用,nullptr 的子节点访问会直接崩溃。
- 入队前必须检查:
if (node->left) q.push(node->left); - 不能写成
q.push(node->left)然后依赖后续判空——此时已解引用了nullptr - 根节点为
nullptr时,整个遍历应直接跳过,避免对空指针调用size()或front()
vector> 存储结果时,每层新建 vector 更安全
常见错误是提前声明一个 vector<int> level</int>,然后在外层循环外反复 clear() ——这在多线程或异常路径下容易出问题,且逻辑不清。
- 推荐在每次外层循环开头定义
vector<int> level;</int> - 内层循环中用
level.push_back(node->val) - 内层结束后再
result.push_back(level) - 这样每层数据生命周期清晰,不会因清空操作残留旧值或迭代器失效
别用 while (!q.empty()) + 计数器模拟分层,易错且不直观
有人试图用全局计数器记录已处理节点数、再跟总节点数比对来“猜”层边界。这在树结构动态变化(比如边遍历边修改)时完全不可靠,而且破坏 BFS 的自然分层语义。
-
q.size()是唯一可靠、无副作用的层长来源 - 不要在循环中多次调用
q.size():它在循环过程中会变,必须在内层循环开始前快照一次 - 如果用
for (int i = 0; i ,注意 C++ 中 <code>q.size()返回size_type(通常是unsigned),与有符号int混用可能触发警告或隐式转换问题;稳妥写法是int n = q.size(); for (int i = 0; i
q.size(),而不是边 pop 边查 size。一旦漏掉这个快照,就会把下一层节点误算进当前层。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











