LinkedList甚至在从递归返回后仍保留值

时间:2012-01-30 06:40:36

标签: java recursion linked-list

我有这个功能来查找BST中从根到叶的所有路径。

public static void paths(Node node, LinkedList<Integer> list) {

    if (node == null) {
        return;
    }
    list.add(node.data);

    if (node.left == null && node.right == null) {
        print(list);
        return;
    } else {
        paths(node.left, list);
        paths(node.right, list);
    }
}

public static void print(LinkedList<Integer> list1) {
    System.out.println("Contents of list: " + list1);
}

我用它来打电话:

LinkedList list = new LinkedList();
paths(bt.root, list);

e.g:

07
02
01 05

打印:

7 2 1
7 2 1 5 [instead of 7 2 5]

不知何故,即使从递归返回后,值1仍保留在“列表”中。

3 个答案:

答案 0 :(得分:4)

正如其他人所说,这里只使用了一个LinkedList对象。 xyz错误地将其描述为使用按引用传递,但它实际上是按值传递 引用的list的值。 (对参数本身的更改,例如为其分配不同的值,对调用者不可见;参数引用的对象内的更改是可见的。)

了解变量,对象和引用在Java中是如何工作的非常非常重要。当你写(说):

Node node = new Node();

...然后node的值不是Node对象。它是Node对象的引用。赋值和参数传递处理该值(引用)而不是对象。例如:

Node node1 = new Node();
Node node2 = node1;

node1node2现在引用相同的对象 - 不涉及对象复制。

至于你如何解决这个问题,我想到两个选择:

  • 在每个递归步骤中创建链接列表的副本,以便更改是独立的
  • 在方法结尾处“弹出”链接列表末尾的新添加值,以便当递归深度n的方法完成时,链接列表返回到{{1} } elements。

您可以通过简单地添加对:

的调用来完成此操作
n-1

在两个分支中,或在finally块中,或删除显式list.removeLast();

return

答案 1 :(得分:3)

我没有看到你从列表中删除任何内容。所以它一旦添加就会停留在那里。

答案 2 :(得分:1)

列表是在递归函数范围之外创建的,这意味着它与所有递归调用中使用的列表相同。您以递归方式向列表中添加元素,因此即使在一个递归序列中值为7 2 51也会在另一个递归序列中添加到同一列表中。