【问题标题】:Unable to set reference variable in recursive call无法在递归调用中设置引用变量
【发布时间】:2014-11-13 15:10:45
【问题描述】:

我正在使用递归方法使用键在二叉树中查找节点。当我找到节点时,我将它设置为我的引用变量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;
    }
}

【问题讨论】:

    标签: java recursion data-structures


    【解决方案1】:

    Java 不通过引用传递参数,而是通过值传递。 Read more here

    让我们通过一个例子来说明。将您要查找的键设为整数,值为21。 函数开头的情况如下:

    所以现在,当你说:

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

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

    简单的解决方案是使用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 了解其背后的原因,或者只是谷歌它。

    【讨论】:

    • 感谢您的澄清,但通过设置 (foundNode = node) 我试图获取具有密钥的节点的引用而不是节点本身。其次,foundNode 只是一个引用变量,因此无法通过调用任何 setter 方法来设置值。
    • 到第二部分,可以。 foundNode 指向您要更改的节点,因此它可以访问该节点的方法。
    • 但是更改节点并不是将引用变量设置为该节点的重点。我需要的只是对该节点的引用。除非我执行 foundNode = node; return foundNode; 之类的操作,否则我不会得到它,并将方法的返回类型从 void 更改为 Node
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2022-11-30
    • 2016-08-06
    相关资源
    最近更新 更多