递归链表反转器

时间:2015-09-24 22:59:44

标签: java recursion linked-list

为java项目创建了一个链表类,需要一个方法来反转列表,这样我和我的朋友最终想出了以下递归方法及它的帮助方法:

(只是为了澄清,first是列表中第一个节点的实例变量)

public void reverse()
{
    first = reverse(first);
}

public Node reverse(Node in) 
{
    if (in == null || in.next == null) 
    {
         return in;
    }

         Node next = in.next;
         in.next = null;
         Node rest = reverse(next);
         next.next = in;
         return rest;
}

当节点包含整数并且我们在列表的开头输入1,2和3时(当添加为第一个节点时它们变为3,2,1)然后尝试将3,2,1转换为成为1,2,3,该功能按计划运行。

我的问题是,我真的无法理解这里发生的事情。

例如,当我跟踪函数(3,2,1)时,它显示为:

next = in.next2, 1)再次传递,直到它只是(1),然后再传递回rest。但是在递归发生之后,rest实际上没有发生任何事情。它发生在next.next,我无法以任何方式弄明next.nextrest的影响。

在冒泡回来期间,我无法找到rest(1)变为(1,2)(1,2,3)的点。

如果有人能够更深入地解释这个函数如何修改rest那将是很好的。我已经追踪了这个函数差不多20次,现在试图理解并且正在发生一些我似乎无法看到的事情。

我甚至把它带给了我的老师,他给了我一些相当于&#34的BS响应;如果它有效,那么它有效,它的递归,不要试图理解它。&# 34; - 那是什么建议?

谢谢

1 个答案:

答案 0 :(得分:1)

尝试绘制一个包含2个节点的列表。这是最简单的例子。

first --> [A] -> [B] -> null

我们调用reverse(first),由于A不为null,我们会产生以下分配:

in = A
next = B

我们在此步骤中打破了A和B之间的联系:

in.next = null;

所以,我们有:

first --> [A]  [B] -> null

现在我们想要其余的,它被分配给这个函数的递归调用,而不是B。我们现在用B重复这些步骤,但由于B.next为空,我们只剩下B。

因此,我们将{B}作为rest的结果返回。我们现在将next.next分配给in,这意味着B.next现在是A

[B] -> [A] -> null
        ^
      first

我们将rest返回给任何调用它的人,在这种情况下,会导致first的分配。

first --> [B] -> [A] -> null

......现在,列表正好相反。

这是它的一般细分;看看它有三个节点,你会看到更多的行为。请记住:每次递归调用都会为innext创建新变量,之前存在的变量将被保留,直到我们从此特定方法返回。