这是反转单链表的正确方法吗?

Is this a correct way to reverse a singly linked list?

这是我想出的用于反转 Java 中的单链表的代码,我想知道它是否正确完成。我知道它的工作原理是完成它的工作并拥有 O(n) 的 运行 时间,但这是一种正确的方法还是可以改进的地方?另外,在反转长链表(不使用迭代替代方案)时,我能做些什么来避免堆栈溢出问题,因为当试图反转大小大于 8300 的链表时,它会导致堆栈溢出异常。

private void reverse(Node node) {
    if(node != this.tail) {
        reverse(node.next);
        this.tail.next = new Node(node.item);
        this.tail = this.tail.next;
        this.head = this.head.next;
    } 
}

public void reverse() {
    reverse(this.head);
}

该解决方案似乎不错,但是您不需要使用旧 Node 对象的值创建新的 Node 对象。您可以反转 singly-linked-list in-place 并在 O(n) 时间复杂度内。

public Node reverse(Node head) {
   Node prev = null;
   while(head!= null) {
      Node rem = head.next;
      head.next = prev;
      prev = current;
      current = rem;
   }
   return prev;  // prev is the new head of your linked list
}

如果您不想使用迭代解决方案(尽管我建议这样做),您可以使用下面的递归解决方案:


public Node reverseList(Node node) { // send the head of the list
   if(current == null) return null;

   reverse(current);
   return this.tail;  // now tail is the head and head is the tail
}
    
public Node reverse(Node node) {
    if(node.next == null) {
        this.tail = node;
    } else {
        reverse(node.next).next = node;
        node.next = null;
    }
    return node;
}

我没有关于您的链接列表的足够详细信息,但我假设您有 this.headthis.tail 字段。即使 this.tail 未初始化,此解决方案也有效。而且,如果预先赋值,就不需要从头遍历链表了。