发布于2026-07-11 阅读(0)
扫一扫,手机访问
二叉树的一次遍历想拿到叶子数量、路径、和、高度?听起来像是要把好几个任务塞进一次DFS里搞定。但问题来了——如果设计不当,递归函数返回的信息不够,后面还得补遍历,效率一下子就没意思了。能不能让一趟递归把所有东西都带出来?能,但有几个关键点必须留意。
先看核心问题:怎么让递归节点“上报”的信息足够完整,同时又不冗余。

直接用 bool 判断“当前节点是不是叶子”看起来挺方便,但一个致命缺陷是:父节点根本不知道底下贡献了多少个叶子。如果想拿到总数,只能再单独遍历一遍,等于白跑一趟。这显然不是我们要的。
推荐的做法是让递归函数返回一个结构体或元组,至少包含叶子数、路径和、高度,以及当前路径(后面要检索完整路径时用)。比如:
struct TreeInfo {
int leaf_count = 0;
int path_sum = 0; // 所有叶子节点值之和
int height = 0;
vector> paths; // 每条从根到叶的路径
};
paths 字段按需保留——若只统计不输出路径,可改为传引用参数避免拷贝{0, 0, -1, {}}(高度为-1,便于 max(left_h, right_h) + 1 统一处理)用 vector 在DFS中记录路径时,最常见的“坑”是递归返回前忘了弹出当前节点的值,结果右子树的路径里混进了左子树的残留数据。
正确的做法必须严格配对:
current_path.push_back(node->val)current_path.pop_back()current_path 拷贝进结果容器如果用结构体返回路径(像上面那个例子),应该在叶子处做 paths.push_back(current_path),而不是在每次递归的入口/出口直接操作 paths——否则路径数量会爆炸式增长。
高度是按“边数”还是“节点数”定义?二者差1,混着用会导致逻辑错位。统一按“节点数”定义更直观——单节点树的高度就是1。
关键边界处理:
height = 0,leaf_count = 0,path_sum = 0height = 1,leaf_count = 1,path_sum = node->valheight = max(left.height, right.height) + 1,leaf_count = left.leaf_count + right.leaf_count,path_sum = left.path_sum + right.path_sum必须注意:path_sum 是所有叶子节点值的总和,不是某条路径上的累加——别跟“根到叶路径和”搞混了。
当树很深、叶子很多时,vector 占用的空间是 O(N×H)(N为叶子数,H为平均深度),远超树本身的 O(N) 存储。如果在生产环境只需要计数或求和,千万别把完整路径存下来。
优化的思路:
paths 字段,用引用参数传计数器和累加器同步计算本身不是瓶颈,真正的“内存杀手”是路径存储。想清楚到底需不需要它,再决定怎么设计。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8