层序遍历求每层平均值需用 levelSize 固定当前层节点数:先 q.size() 记录,再 for 循环处理;必须判空 root,否则解引用空指针崩溃;sum 用 double 避免整除截断。

用 std::queue 做层序遍历,别直接 push root 后就 while(!q.empty()) 循环到底
层序遍历本质是 BFS,但算每层平均值时,必须明确区分“当前层”和“下一层”。如果只靠 q.empty() 判断,会丢失层边界,导致平均值全混在一起。
正确做法是每次进入循环前,先记录队列当前大小 int levelSize = q.size(),然后用 for 循环处理这 levelSize 个节点——它们属于同一层。
- 错误写法:
while (!q.empty()) { auto n = q.front(); q.pop(); /* 处理n */ if (n->left) q.push(n->left); ... }→ 无法分层求和 - 正确结构:外层
while (!q.empty()),内层for (int i = 0; i -
levelSize必须在 for 循环前获取,因为 push 操作会实时改变q.size()
计算每层平均值时,注意整数溢出和类型转换
节点值是 int,但一层可能有上百个节点,累加和容易超出 int 范围。更关键的是,C++ 中 sum / count 如果都是 int,结果会截断小数部分,导致平均值全为整数。
- 累加变量必须用
long long或double,推荐double sum = 0.0 - 除法前至少一个操作数转为浮点型:
sum / static_cast<double>(count)</double>,否则仍执行整除 - 如果题目要求返回
vector<double></double>,直接 push 这个结果即可,无需四舍五入
空树和单节点树要单独验证,root == nullptr 时别进主循环
很多实现一上来就 q.push(root),但若 root 是 nullptr,后续 q.front()->val 会崩溃。标准库不会帮你解引用空指针。
立即学习“C++免费学习笔记(深入)”;
- 开头必须判断:
if (!root) return {}; - 初始化队列只在非空时进行:
queue<treenode> q; q.push(root);</treenode> - 单节点树(只有 root)会走一次外层 while,内层 for 执行 1 次,
sum就是root->val,结果正确 - LeetCode 测试用例包含空树,不判空会 runtime error: member access within null pointer
完整可跑的最小代码骨架,去掉冗余注释和异常处理
vector<double> averageOfLevels(TreeNode* root) {
if (!root) return {};
queue<TreeNode*> q;
q.push(root);
vector<double> res;
while (!q.empty()) {
int levelSize = q.size();
double sum = 0.0;
for (int i = 0; i < levelSize; ++i) {
TreeNode* n = q.front(); q.pop();
sum += n->val;
if (n->left) q.push(n->left);
if (n->right) q.push(n->right);
}
res.push_back(sum / levelSize);
}
return res;
}
这个版本没做输入校验、没用智能指针、也没考虑自定义分配器——实际刷题或嵌入逻辑时,这些反而增加出错概率。真正卡住人的,从来不是语法,而是 levelSize 的获取时机和 sum 的类型。


















