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

递归实现二叉树节点计数方法返回0问题求助

问题分析与解决方案

嘿,你猜得完全没错!问题的核心就是Integer的不可变性加上Java的参数传递机制导致的,我来给你掰扯清楚,再给你几个可行的修复方案。

为什么你的代码返回始终是0?

Java里的参数传递是值传递——对于对象类型来说,传递的是对象引用的副本。而Integer是个不可变类,当你执行cardinalidade = cardinalidade + 1的时候,根本不是修改原来的Integer对象的值,而是创建了一个全新的Integer实例,并且让当前方法里的cardinalidade引用指向这个新对象。但你在contaNos方法里声明的那个原始cardinalidade引用,从头到尾都没变过,一直指向初始值0的那个Integer对象,所以最后返回自然还是0。

修复方案

方案1:用可变容器类包裹整数(适合理解原理)

既然Integer不可变,那我们可以自己写一个简单的可变容器类,把int值装进去,这样传递的是容器对象的引用,修改容器里的属性就会影响到原始对象:

public int contaNos(Arvbin r) {
    IntWrapper cardinalidade = new IntWrapper();
    contaNosPrivado(r, cardinalidade);
    return cardinalidade.value;
}

private void contaNosPrivado(Arvbin r, IntWrapper cardinalidade) {
    if (r == null) {
        return;
    }
    cardinalidade.value++; // 直接修改容器里的int值
    contaNosPrivado(r.esq, cardinalidade);
    contaNosPrivado(r.dir, cardinalidade);
}

// 内部可变容器类
private static class IntWrapper {
    int value = 0;
}

方案2:让递归方法返回节点数(推荐,更简洁)

其实统计二叉树节点数的常规递归写法,根本不需要用参数传递计数,直接让递归方法返回当前子树的节点数就好,代码更干净,也避免了可变对象的问题:

public int contaNos(Arvbin r) {
    return contaNosPrivado(r);
}

private int contaNosPrivado(Arvbin r) {
    // 空树节点数为0
    if (r == null) {
        return 0;
    }
    // 当前节点数1 + 左子树节点数 + 右子树节点数
    return 1 + contaNosPrivado(r.esq) + contaNosPrivado(r.dir);
}

这种写法完全符合递归的思想,每一层递归只需要关注当前节点的情况,累加左右子树的结果,逻辑清晰还不容易出错。

内容的提问来源于stack exchange,提问作者João Vitor Sousa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:07:06