用std::queue做bfs层序遍历需先记录当前队列大小再执行对应次数的内层循环,以准确划分层级;入队前须判空避免空指针解引用;调试时可用std::deque替代观察内容。

用 std::queue 做 BFS 是最直接的方式
层序遍历本质就是广度优先搜索(BFS),C++ 标准库的 std::queue 天然适配 FIFO 特性,不需要手写队列或依赖第三方容器。关键在于每次处理「当前层全部节点」,而不是逐个弹出就完事。
常见错误是只用一个 while (!q.empty()) 循环,导致无法区分层界——结果能遍历完所有节点,但拿不到每层的节点数或独立数据块。
实操建议:
- 每轮循环开始前,记录
q.size()作为本层节点总数 - 用内层
for循环固定执行q.size()次,确保只处理当前层节点 - 在内层循环中完成取值、存入临时容器、压入子节点等操作
- 内层结束后,把该层数据(如
vector<int></int>)推入最终结果vector<vector>></vector>
TreeNode 结构定义和空节点处理要一致
标准 TreeNode 通常含 val、left、right 三个成员。但实际编码时容易忽略:是否允许 nullptr 入队?怎么避免访问空指针?
典型错误现象:runtime error: member access within null pointer,往往出现在未判空就调用 node->left->val 或直接 push nullptr 后后续又试图解引用。
实操建议:
- 入队前必须检查
node->left和node->right是否非空,只 push 非空指针 - 出队后第一件事是判空(虽然按上述规则不会出现,但加一层防御更稳)
- 若题目要求保留空层信息(如 LeetCode 102 的变体),需改用标记法或分隔符,但常规统计每层节点数无需这么做
性能敏感场景下避免重复构造临时容器
如果树很深、每层节点很多,频繁对每层新建 vector<int></int> 并 push_back 可能引发多次内存分配。虽然对一般 OJ 题目影响不大,但在嵌入式或高频服务中值得优化。
实操建议:
- 提前用
res.reserve(expected_max_level)预留外层数组容量 - 内层 vector 改用
vector<int>(level_size)</int>构造指定大小,再用下标赋值,避免动态扩容 - 若只需统计每层节点数量(不要求具体值),可跳过存储值的过程,仅计数,空间从 O(n) 降到 O(w),w 为最大层宽
遇到 std::queue 不能直接遍历的问题怎么办
std::queue 默认不支持迭代器,所以没法用范围 for 或 std::for_each 查看内部元素——这常让调试者误以为“队列没装进去”或“数据丢了”。其实只是封装限制,不影响功能。
实操建议:
- 调试时改用
std::deque替代(它支持随机访问),临时替换queue<t></t>为deque<t></t>,用q[i]观察内容 - 或者在每层处理前后打印
q.size()和首尾节点值(需额外保存)来验证逻辑 - 切勿为调试而改用
std::vector+ 手动维护头尾索引——增加出错概率且无必要
真正容易被忽略的是层边界判断时机:必须在进入内层循环前获取 q.size(),而不是在循环中用 q.size() 做条件,否则边 pop 边变化的 size 会导致漏节点或死循环。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











