无法在递归调用中设置引用变量

时间:2014-09-19 05:19:43

标签: java recursion data-structures

我使用递归方法使用密钥在二叉树中查找节点。当我找到节点时,我将其设置为我的引用变量foundNode并返回。问题是,当我读取对象时,它的值仍为null。有人可以帮忙吗?

findGivenNode(root, key, foundNode, parentStack);

private boolean findGivenNode(Node node, int key, Node foundNode, Stack<Node> parentStack) {
    if (node == null) {
        return false;
    }

    parentStack.add(node);
    if (node.getData() == key) {
        foundNode = node;
        return true;
    }  
    boolean leftReturn = findGivenNode(node.getLeftChild(), key, foundNode, parentStack);
    boolean RightReturn = findGivenNode(node.getRightChild(), key, foundNode, parentStack);        
    if (leftReturn || RightReturn) {
        return true;
    }  else {
        parentStack.pop();
        return false;
    }
}

1 个答案:

答案 0 :(得分:2)

Java不通过引用传递参数,它们是按值传递的。 Read more here

让我们通过一个例子来澄清。使您要查找的键为值21的整数。 该函数开头的情况如下:

initial_state

现在,当你说:

foundNode = node; // this doesn't reflect outside of the method

您正在foundNode方法中本地更改findGivenNode()的值,它不适用于此方法之外。基本上,名为foundNode的局部变量引用要更改的节点,然后通过上面的语句使此局部变量foundNode引用新节点。 此更改仅反映在函数内部。一旦您的函数完成,本地变量就不再存在,因此foundNode的本地版本也不存在。视觉效果:

wrong_move

简单的解决方案是使用Wrapper function

要跟踪引用,您可以创建一个简单的包装类来存储所需的引用:

private class NodeWrapper {
    Node foundNode;
    NodeWrapper() {
        foundNode = null;
    }
}

然后你可以创建一个新的NodeWrapper并将其传递给你的函数而不是foundNode

NodeWrapper wrapper = new NodeWrapper();
findGivenNode(root, wrapper, key, parentStack);

然后在你的函数内部而不是:

foundNode = node;

你说:

wrapper.foundNode = node;

这样,您可以在NodeWrapper内的整个递归中维护引用。含义:

NodeWrapper wrapper = new NodeWrapper();
findGivenNode(root, wrapper, key, parentStack);
// at this point, wrapper.foundNode will hold the reference to the node you need
// or null if the node wasn't found

另外注意,在方法上方你有这个函数原型:

findGivenNode(root, key, foundNode, parentStack);

似乎某人仍然习惯于C / C ++:)

这在Java中是不必要的,您可以阅读this question thread以了解其背后的原因,或只是谷歌。