二叉搜索树节点求和递归方法结果异常,请求技术协助
问题根源:Java值传递的经典陷阱
哥们,我一眼就看穿你遇到的问题了——这完全是Java值传递机制搞的鬼!咱们来拆解一下为什么从左子树切到右子树时总和会“减少”:
原代码的核心问题
Java里的基本类型(比如你用的int)是按值传递的,也就是说每次调用sumTree时,传入的sum都是当前值的一个副本。你在递归左子树的时候,对sum的修改只会作用在那个副本上,根本不会影响当前方法里的sum变量。等左子树递归完回到当前层,sum还是你调用左子树之前的数值,再去递归右子树时,相当于重新用旧的sum去累加右子树,自然就没把左子树的结果算进去,看起来总和反而“倒退”了。
举个实际例子:假设根节点是5,左子树是3,右子树是7。原代码执行流程是这样的:
- 初始sum=0,根节点加5 → sum=5
- 调用左子树
sumTree(3,5),在左子树里sum变成8,但这是副本,回到根节点sum还是5 - 调用右子树
sumTree(7,5),sum变成12,同样是副本,最后根节点返回的sum还是5
最终结果完全错误,正确的总和应该是15才对!
两种修正方案
方案1:让递归方法返回子树总和(最简洁推荐)
直接去掉sum参数,让每个递归调用负责计算自己所在子树的总和,上层直接累加当前节点值+左子树总和+右子树总和:
public static int sumTree(TreeNode root) { // 空节点贡献0 if (root == null) { return 0; } // 当前节点值 + 左子树总和 + 右子树总和 int currentVal = (Integer) root.getValue(); return currentVal + sumTree(root.getLeft()) + sumTree(root.getRight()); }
调用的时候直接拿返回值就行:
int totalSum = sumTree(root);
方案2:用可变容器传递sum(适合需要保留参数的场景)
如果一定要通过参数传递sum,可以用一个可变的容器(比如数组、自定义类)来包装int,因为引用类型是按引用传递的(准确说是传递引用的副本,但修改容器内的内容会反映到原对象):
public static void sumTree(TreeNode root, int[] sumHolder) { if (root != null) { System.out.println("current value: " + root.getValue()); // 修改数组里的元素,会反映到外部的sumHolder sumHolder[0] += (Integer) root.getValue(); System.out.println(sumHolder[0]); sumTree(root.getLeft(), sumHolder); sumTree(root.getRight(), sumHolder); } }
调用方式:
// 用数组包装初始值0 int[] sumHolder = {0}; sumTree(root, sumHolder); int totalSum = sumHolder[0];
关键知识点回顾
Java里没有真正的“引用传递”:
- 基本类型传递的是值的副本,方法内修改副本不影响原变量
- 引用类型传递的是引用的副本,修改引用指向的对象内容会影响原对象,但修改引用本身(比如把引用指向新对象)不会影响原引用
内容的提问来源于stack exchange,提问作者Flyrom
相关产品推荐
相关产品推荐

