You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二叉搜索树节点求和递归方法结果异常,请求技术协助

问题根源:Java值传递的经典陷阱

哥们,我一眼就看穿你遇到的问题了——这完全是Java值传递机制搞的鬼!咱们来拆解一下为什么从左子树切到右子树时总和会“减少”:

原代码的核心问题

Java里的基本类型(比如你用的int)是按值传递的,也就是说每次调用sumTree时,传入的sum都是当前值的一个副本。你在递归左子树的时候,对sum的修改只会作用在那个副本上,根本不会影响当前方法里的sum变量。等左子树递归完回到当前层,sum还是你调用左子树之前的数值,再去递归右子树时,相当于重新用旧的sum去累加右子树,自然就没把左子树的结果算进去,看起来总和反而“倒退”了。

举个实际例子:假设根节点是5,左子树是3,右子树是7。原代码执行流程是这样的:

  1. 初始sum=0,根节点加5 → sum=5
  2. 调用左子树sumTree(3,5),在左子树里sum变成8,但这是副本,回到根节点sum还是5
  3. 调用右子树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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:08:27