当前位置: 首页 > 知识库问答 >
问题:

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

沃念
2023-03-14

我使用递归方法在二叉树中使用键查找节点。找到节点后,我将其设置为引用变量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个答案

岳正阳
2023-03-14

Java不通过引用传递参数,而是通过值传递。在此处阅读更多信息

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

现在,当你说:

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

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

简单的解决方案是使用包装函数

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

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

然后您可以创建一个新的NodeWrapper并将其传递到您的函数中,而不是findNode

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);

似乎有人还习惯于抄送:)

这在Java中是不必要的,您可以阅读这个问题线程来进行推理,或者只是用谷歌搜索它。

 类似资料:
  • 我最近实现了一个4X4井字游戏的代码,这是使用极大极小算法。然而,我的极大极小函数无限次地递归调用自己。 初始板 (4X4) 井字 - 轮到电脑的代码- 在上面的代码中是船上的空位置,返回“X”(如果玩家X获胜),返回“O”(如果玩家O获胜) checkGameOver函数-

  • 需求:生成一个集合的所有可能组合的算法,没有重复项,或者递归调用函数返回结果。 在JavaScript中排列提供的大部分答案,如果不是全部的话?从循环或其他函数中递归调用函数以返回结果。 循环内递归函数调用示例 在为一个集合确定了各个置换的总数之后,可以使用、和创建并填充包含所有六个置换的结果数组 在计算排列和工作面试问题时,试图根据图中显示的模式再现有序词典排列算法的结果,该算法是基于C++实用

  • 想改进这个问题吗 通过编辑这篇文章,更新问题,以便用事实和引文来回答。 我有以下递归方法: 在本例中,当我调用其中的方法时,以及使用方法I时,会再次创建parentUuids,并且会丢失其值。 另一方面,当使用如下所示的方法II时,我保留了值: 我的问题是: 1.方法II是保留局部变量值的正确方法吗? 2.这是一种特殊的用法吗?它叫什么名字?我以前从未使用过这种方法,但我认为它可能对这种情况有用。

  • 问题内容: 我正在编写A 来执行一些我需要在读/写时完成的转换任务。特别是,我要采用现有的序列化行为,并在写入时添加一些其他属性/在读取时读取这些其他属性。 在中,我想利用传递的实例来执行大多数转换功能。但是,当我这样做时,我最终陷入了递归循环,在此循环中,序列化程序调用了我的转换器,后者又调用了序列化程序,后者又调用了转换器等。 我看到人们做诸如使用之类的事情,从序列化器实例中传入所有的转换器,

  • 我正在ApacheSpark上的数据库中构建一个族谱,使用递归搜索来查找数据库中每个人的最终父级(即族谱顶部的人)。 假设搜索id时返回的第一个人是正确的家长 它给出以下错误 “原因:org.apache.spark.SparkException:RDD转换和操作只能由驱动程序调用,不能在其他转换中调用;例如,

  • 我写了下面的代码来反转链表的前K个节点,它在反转链表的前K个节点时解决了一些问题,为什么递归在最后一次迭代中执行两次,现在它可以正常工作,但为什么它会导致链表中的循环当我尝试在“if”条件下使用变量“k”而不是“PresCouner”时,原因是什么?以及如何避免它?