繁体   English   中英

反向链接列表

[英]Reversing a linked-list

我正在编写一个简单的递归代码来反转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;
}

为什么这不起作用?

您当前的方法行不通,从递归调用返回的rest值不指向列表中的最后一个元素(应该是节点的插入点),而是指向该对象的第一个元素。结果。 换句话说,此行未正确构建输出:

rest.link = ptr;

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

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()之前创建list的副本。

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

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

function reverse(node) {
  if (node.next == null)
    return node;
  var tail = reverse(node.next);
  node.next.next = node;
  node.next = null;
  return tail;
}
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;}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM