简体   繁体   English

二叉树节点递归的递归方法

[英]Recursive method for binary tree node couting

Ok, so i have to create a recursive method for counting the nodes in a tree, and i did this (variable names are in portuguese, sorry): 好的,所以我必须创建一个递归方法来计算树中的节点,而我做到了(变量名是葡萄牙语),对不起:

public int contaNos(Arvbin r) {
        Integer cardinalidade = 0;
        contaNosPrivado(r, cardinalidade);
        return cardinalidade;
}
private void contaNosPrivado(Arvbin r, Integer cardinalidade) {
        if (r==null) {
            return;
        }
        cardinalidade=cardinalidade+1;
        contaNosPrivado(r.esq, cardinalidade);
        contaNosPrivado(r.dir, cardinalidade);
        return;
}

Arvbin is the binary tree, esq and dir are the left and right references to the tree's branches. Arvbin是二叉树,esq和dir是对该树分支的左右引用。

I thought this would work, but for some reason when i try to run it, it returns 0. I've usen a little bit of debugging and i think the issue is that when the methods finish and come back to the original non-recursive one, the cardinalidade variable is set to 0. I'm not sure if it's because autoboxing is messing with my Integer and turning it into an int, and then when i call the method it passes a copy of the value instead of the reference to the existing object, and i don't know how to fix it. 我认为这可以工作,但是由于某种原因,当我尝试运行它时,它返回0。我已经使用了一些调试功能,我认为问题是方法完成后又回到原始的非递归状态一个,cardinalidade变量设置为0。我不确定是否是因为自动装箱弄乱了我的Integer并将其转换为int,然后当我调用该方法时,它传递了值的副本,而不是引用现有的对象,我不知道如何解决。 If anyone could help, i'd greatly appreciate it 如果有人可以帮忙,我将不胜感激

The problem is that wrapper classes are immutable in Java. 问题在于包装类在Java中是不可变的。 cardinalidade is just a parameter of contaNosPrivado here and, unfortunately, cannot act as an argument like other object type parameters can, ie this local reference cannot change inner fields of the object that initial reference refers. cardinalidade仅仅是一个参数contaNosPrivado这里,不幸的是,不能作为一个参数像其他对象类型的参数可以,即,这个本地参考不能改变对象的内部字段初始参考指。 Any change to it affects it only the way it affects any primitive local variable. 对它的任何更改只会以影响任何原始局部变量的方式影响它。

What exactly happens inside your contaNosPrivado : 您的contaNosPrivado内部到底发生了什么:

  1. On invocation, it is indeed supplied a reference to an Integer object. 在调用时,确实为它提供了对Integer对象的引用。 This reference is assigned to a local variable named cardinalidade . 该引用分配给名为cardinalidade的局部变量。
  2. In this line: 在这一行:

     cardinalidade=cardinalidade+1; 

    this object is first unboxed to a primitive int variable, this variable is incremented afterwards, and finally the result is reboxed into a new Integer object which is then assigned to cardinalidade . 首先将该对象取消装箱到原始int变量,然后将该变量递增,最后将结果重新装箱到新的 Integer对象,然后将其分配给cardinalidade There is no way to 'increment' original object, even if you use the increment operator: 即使使用增量运算符,也无法“增量”原始对象:

     cardinalidade++; 
  3. Any further processing applies to the newly created Integer object and doesn't affect the reference passed to contaNosPrivado . 任何进一步的处理都将应用于新创建的Integer对象,并且不会影响传递给contaNosPrivado的引用。

To achieve your goals, use something like this instead: 为了实现您的目标,请改用以下方法:

static int contaNosPrivado(Arvbin r) {
    if (r == null)
        return 1;
    else
        return contaNosPrivado(r.esc) + contaNosPrivado(r.dir);
}

As @John McClane has pointed out, you can't pass an Integer argument by reference , only by value . 正如@John McClane指出的那样,您不能通过引用传递Integer参数,只能通过value传递。

But there's also no need for a private helper method, you can just simplify it all to a single method: 但是也不需要私有的辅助方法,您可以将所有方法简化为一个方法:

public int countLeaves( BinaryTreeNode n )
{
    return n == null? 0 : ( countLeaves( n.rightLeaf ) + countLeaves( n.leftLeaf ) );
}

Or (excuse my poor Portugese): 或者(对不起我可怜的葡萄牙语):

public int contaNos( Arvbin r )
{
    return r == null? 0 : ( contaNos( r.esq ) + contaNos( r.dir ) );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM