【问题标题】:Reversing a linked-list反转链表
【发布时间】:2014-06-28 13:46:00
【问题描述】:

我正在编写一个简单的递归代码来反转 Java 中的链表。奇怪的是它返回相同的节点。

Node reverse(Node ptr) {
    if (ptr.link == null)
        return ptr;

    Node second = ptr.link;
    ptr.link = null;

    Node rest = reverse(second);
    rest.link = ptr;

    return rest;
}

为什么这不起作用?

【问题讨论】:

    标签: java recursion linked-list reverse


    【解决方案1】:

    您当前的方法不起作用,从递归调用返回的 rest 值不指向列表中的 last 元素(这应该是节点),而是指向结果的 first 元素。换句话说,这一行没有正确构建输出:

    rest.link = ptr;
    

    为了成功地反转列表,一种策略是使用累加器参数,因此我们可以在递归展开时插入列表的头部 - 请记住,递归开始以相反的顺序“返回”到列表中的元素。试试这个,这是tail-recursive 解决方案:

    Node reverse(Node ptr, Node acc) {
        if (ptr == null)
            return acc;
        Node second = ptr.link;
        ptr.link = acc;
        return reverse(second, ptr);
    }
    

    像这样调用上面的方法:

    Node reversedList = reverse(list, null);
    

    请注意,输入 list 将被就地修改,并且在方法返回后不会相同,任何持有对 list 的引用的变量都会受到影响。如果这是个问题,您应该先创建一个 list 的副本,然后再将其传递给 reverse()

    【讨论】:

    • 我有Node ob,我正在其中进行所有计算。我将其称为Node ob1 = reverse(ob,list); ob1.display();,其中display只是打印列表。但它正在打印相同的列表。我调用函数的方式不对吗?
    • @Faustus 您发布的反向算法是错误的,根据评论不清楚您是如何打印的。从头开始,以我的答案为起点,它的工作代码。也有可能是显示代码错误。
    【解决方案2】:

    Oscar 是正确的,递归调用的返回值没有指向最后一个元素。

    还有一种算法不使用累加器参数:

    function reverse(node) {
      if (node.next == null)
        return node;
      var tail = reverse(node.next);
      node.next.next = node;
      node.next = null;
      return tail;
    }
    

    【讨论】:

      【解决方案3】:
      Node reverseNode(Node node){
      Node head = null;
      While(node.next != null){
          Node n = new Node(node.data);
          n.next = head;
          head = n;
          node = node.next;
      }
      return head;}
      

      你知道你不必编写递归函数

      【讨论】:

        猜你喜欢
        • 2021-05-21
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多