应使用 std::queue 而非手写链表,因其 push/front/pop 均为 O(1)、底层基于 std::deque 且内存局部性好;手写链表易出现指针错误,且无必要重复造轮子。

为什么用 std::queue 而不是手写链表做层序遍历
因为 std::queue 的 push() 和 front()/pop() 操作都是 O(1),且底层通常基于 std::deque,内存局部性好;手写链表容易在指针管理上出错,比如漏删节点或重复释放。实际项目里,除非有特殊内存约束(如嵌入式场景禁止 STL),否则直接用 std::queue<treenode></treenode> 更稳。
注意:必须存指针(TreeNode*),不能存 TreeNode 值对象——否则会触发拷贝构造,二叉树结构丢失,还可能栈溢出。
queue.size() 在循环中要“快照”一次
层序遍历时,常需按层处理(比如统计每层节点数、找每层最大值)。这时不能在 while (!q.empty()) 里直接用 q.size() 控制内层循环,因为 q.size() 是实时变化的。
- 错误写法:
for (int i = 0; i —— 每次调用 <code>q.size()都返回当前长度,循环次数会变 - 正确写法:先
int levelSize = q.size();,再for (int i = 0; i
这个细节一漏,遍历就乱序,深度统计结果偏小,调试时很难定位。
立即学习“C++免费学习笔记(深入)”;
深度统计别只靠 while 循环次数
仅靠外层 while (!q.empty()) 的循环次数算深度,只适用于「完全二叉树」或「所有叶子都在最底层」的情况。真实二叉树可能左右子树高度差很大,必须结合节点层级信息。
推荐做法:每个入队节点附带其深度,用 std::queue<:pair int>></:pair> 或封装结构体。例如:
queue<pair<TreeNode*, int>> q;
q.push({root, 1});
while (!q.empty()) {
auto [node, depth] = q.front(); q.pop();
maxDepth = max(maxDepth, depth);
if (node->left) q.push({node->left, depth + 1});
if (node->right) q.push({node->right, depth + 1});
}
如果只关心最大深度,不关心每层内容,其实 DFS 更简洁;但题目明确要求「层序遍历」+「深度统计」,那就得在 BFS 过程中带深度状态走。
空树和单节点树的边界情况必须显式检查
很多实现直接对 root 调用 q.push(root),但若 root == nullptr,就会 push 空指针,后续 q.front() 解引用崩溃。同样,单节点树时,深度应为 1,不是 0。
- 入口处加
if (!root) return 0; - 初始化
maxDepth = 0,然后在 push 前确保root非空,再设maxDepth = 1或靠循环内更新
这些判断看着琐碎,但线上服务遇到空输入崩溃,往往就卡在这两行没写。


















