【问题标题】:Recursion In Merging Linked Lists合并链表中的递归
【发布时间】:2018-11-24 01:36:59
【问题描述】:

我开始理解递归了,

我附上了合并两个排序链表的递归代码,

我的问题是,我知道一旦第一个或第二个变为空,'temp' 返回 temp->(first (or) second) 的值,但我无法理解这一事实,

例如,如果我有 5 -> 10 -> 15 -> 20。

最终函数返回 15 ->20,然后将其组合为 root.next-> temp,但是在我返回 temp 的那一步之后,为什么会返回根值。 即 10 -> 15 -> 20,当我希望只返回 temp 时。

请找到代码,

 /**
 * 
 */
 *
 *
 */
public class MergeLinkedLists {

    static class Node {

        int data;
        Node next;

        public Node(int value) {
            this.data = value;
        }

    }

    Node root;

        /**
     * @param args
     */

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MergeLinkedLists s1 = new MergeLinkedLists();
        s1.root = new Node(0);
        Node n1 = new Node(10);
        //n1.next = new Node(20);
        //n1.next.next = new Node(30);

        Node n2 = new Node(5);
        n2.next = new Node(15);
        //n2.next.next = new Node(50);

        Node result = sortedLists(n1, n2, s1.root);

        while (result != null) {
            System.out.print(result.data + "--->");
            result = result.next;
        }
    }

    /**
     * @param n1
     * @param n2
      * @param root2
     */
     private static Node sortedLists(Node n1, Node n2, Node root) {
         // TODO Auto-generated method stub

        Node temp = root;

        Node first = n1; // 10 20 30
        Node second = n2; // 5 15 50

        if (first == null) {
            temp.next = second;
            return temp;
        } else if (second == null) {
            temp.next = first;
            return temp;
        }

        else if (first.data < second.data) {
            temp = new Node(first.data);
            first = first.next;
        } else {
            temp = new Node(second.data);
            second = second.next;
        }

        sortedLists(first, second, temp);
        root.next = temp;
        System.out.println("The Temp Data is ::::"+temp.data);
        return temp;

    }

}

【问题讨论】:

  • 欢迎来到 SO!这个函数的编写方式非常混乱,但据我所知,它工作得很好。你能澄清你的问题是什么吗?此处的返回值无关紧要,除了第一个函数调用,它将正确的结果(虚拟根的下一个值,即root.next)返回到主范围。

标签: java recursion data-structures linked-list


【解决方案1】:

因为temp 在这种情况下是根值。别担心,这是为了理解递归本身需要理解的一件事。

了解代码功能的一个重要功能是使用调试器。为函数调用设置断点,您可以单步执行程序,同时可以观察变量如何变化。

除此之外,让我们看看你的代码。

需要注意的是,每当您调用sortedLists(first, second, temp); 时,指针都会进入其中,直到函数终止(因此当它返回 temp 时)。随着程序的继续,您将多次调用此函数,因此它将更深入地了解自己的函数。 然后它一步一步地传递信息直到sortedLists(first, second, temp); 的第一次调用终止,这是在你的主要方法Node result = sortedLists(n1, n2, s1.root);

我会尽量配合你的例子:

  1. Node result = sortedLists(n1, n2, s1.root);在main()方法中调用。所以根是 0,你的节点是 10 和 5,15。

  2. 在sortedLists() 的第一次调用中,temp 变为5,second 现在带有15,因为first.data &gt; second.data。

  3. 现在您再次调用方法 sortedLists(),但使用了新值:根现在是 5,第一个仍然是 10,第二个是 15。我们进入函数内部并从新值开始:

    1. 由于first.data &lt; second.data,temp 变为10,first 现在为null。
    2. 又一次:我们在sortedLists() 上打了另一个电话。我们将值:first = null second = 15 root = 10 传递给函数并更深入一步。
      1. 因为first 现在为零,temp.next 将是second(15)
      2. temp 现在看起来像这样:10->15 我们返回。 (这是第一次,sortedLists() 终止!)
    3. 我们现在回到这里,可以继续使用root.next = temp; 还记得在这种情况下的 temp 吗? temp 为 10,但已由上面的函数更新。新的temp 是 10->15,所以我们的root 看起来像:5->10->15。
    4. 然后打印 temp 的头部,即 10。此函数也终止。
  4. 现在我们回到第一次调用,看看会发生什么:在 3.3 中,我们更新了它的根。 3.3 的根是 3 的 temp,因为我们调用了 sortedLists(first, second, temp)(temp 充当根,因为此函数的最后一个参数是 Node root)。

  5. 总结一下:我们的根还是0,温度是5->10->15

  6. root.next 在此分配 0->5->10->15 之后。现在,您在 main 方法上方的类中声明的根有一个值。

  7. 我们返回 5->10->15 的温度,我们就完成了。

我们现在可以继续主方法,打印结果。

要去掉--->当没有result.next时,可以这样处理空值:

 while (result != null) {
            if (result.next != null)
            System.out.print(result.data + "--->");
            else System.out.println(result.data);
            result = result.next;
        }

我希望这对递归有所帮助。

【讨论】:

  • 您好 e.Fro,非常感谢您的建议,我对您所说的第 4 步有一点疑问,3.3 的根是 3 的温度 ...我明白了.. .但是当3.3的函数调用终止时,如何返回根值......我只返回temp。 ( 10-> 15) .... 所有值都返回到之前的调用函数....提前致谢。
  • 我猜整个概念是基于值传递,当被调用函数的根值被更新时,它会反映在调用函数的临时值中。如果我错了,请纠正我!
  • 关于 Java 中的对象要记住的一点是,除非您重新创建它们(new object()),否则它们是唯一的。因此,您的函数传递 temp 对象,并且被调用函数将 same 对象分配为根。但是对象本身保持不变。所以如果你改变它,你不仅仅是改变它的值,你的操作会对整个对象产生影响。这是一个巨大的优势,因为您可以节省大量空间。所以没有必要返回,这就是为什么你不在递归中处理返回。您只需操纵对象本身
  • 这种方式称为in-place,也用于快速排序。在喜欢列表的上下文中,它非常有用,因为您不想继续创建新元素进行操作。我希望我能帮助你一点。 en.m.wikipedia.org/wiki/In-place_algorithm
  • 我建议在您的方法上使用调试器,以查看上层的临时对象何时更改。我认为这会有很大帮助。
猜你喜欢
  • 2015-07-19
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 2017-08-02
  • 2017-04-21
相关资源
最近更新 更多