层序遍历需用队列长度控制每层批量处理:每次while循环前记录q.size(),再for循环处理该层所有节点;sum须用long long防溢出,除法前static_cast(sum)/size防整数截断;空树返回空vector,单节点树正确返回根值。

用 std::queue 做层序遍历,别直接 push root 后就 while(!empty()) 循环到底
层序遍历本质是按「层」推进,不是单纯把节点塞进队列就完事。如果每次只取一个节点、再把它的左右子节点 push 进去,你根本不知道当前取的是哪一层的节点——也就没法在换层时统计平均值。
关键做法是:每轮循环前先记录当前队列长度,这个长度就是本层节点数。然后用 for 循环精确 pop 出这 size 个节点,期间把它们的子节点加入队列,但不干扰本轮计数。
- 错误写法:
while (!q.empty()) { auto n = q.front(); q.pop(); sum += n->val; if (n->left) q.push(n->left); ... }→ 无法区分层界 - 正确节奏:每次进入 while 前读一次
q.size(),for 循环内处理完这一层所有节点 -
std::queue没有随机访问,所以必须靠 size + for 控制“批量处理”
计算每层平均值时,注意整型溢出和类型转换
节点值是 int,但一层可能有上百个节点,sum 累加容易溢出;更隐蔽的问题是:用 sum / count 直接除会触发整数截断,即使你声明了 double avg,除法本身已在 int 范围内完成。
- 务必把
sum声明为long long或double(推荐前者,避免浮点误差) - 除法前强制转类型:
static_cast<double>(sum) / count</double>,不能只转结果变量 - 如果题目要求返回
vector<double></double>,中间不用存整数,直接 push 转换后的 double
空树和单节点树要能过,别漏掉边界判断
输入可能是 nullptr,也可能是只有根节点的树。前者要求返回空 vector;后者要求结果中只有一个平均值,且等于根节点值。
立即学习“C++免费学习笔记(深入)”;
- 函数开头必须判
if (!root) return {}; - 初始化队列后立刻 push
root,不要在 while 内部才考虑是否 push —— 否则单节点树会跳过整个循环 - 测试时可快速验证:
root = new TreeNode(5)→ 输出应为[5.0]
完整可跑的最小实现,不含类封装,专注逻辑主干
下面这段去掉注释就能编译运行(需包含 <queue></queue>, <vector></vector>, <treenode></treenode> 定义):
vector<double> averageOfLevels(TreeNode* root) {
if (!root) return {};
vector<double> res;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
long long sum = 0;
for (int i = 0; i < size; ++i) {
auto 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(static_cast<double>(sum) / size);
}
return res;
}
真正容易卡住的,是忘记 size 必须在 for 外获取,以及 sum 类型没升级导致大层数据算错。这两处一错,测试用例看着过了,但遇到深度 10、每层 2^9 个节点时就会崩。


















