Java 如何反转链接列表?

Java 如何反转链接列表?,java,algorithm,data-structures,linked-list,singly-linked-list,Java,Algorithm,Data Structures,Linked List,Singly Linked List,考虑: Node reverse(Node head) { Node previous = null; Node current = head; Node forward; while (current != null) { forward = current.next; current.next = previous; previous = current; current = forward;

考虑:

 Node reverse(Node head) {
    Node previous = null;
    Node current = head;
    Node forward;

    while (current != null) {
        forward = current.next;
        current.next = previous;
        previous = current;
        current = forward;
    }

    return previous;
}
它到底是如何颠倒清单的

我知道它首先将第二个节点设置为
forward
。然后它说
current.next
等于
null
节点
previous
。然后它说以前的现在是当前的。最后,
当前
变为
向前


我似乎无法理解这一点以及它是如何逆转的。有人能解释一下这是如何工作的吗?

您可以迭代地反转列表,并且始终正确地反转间隔[head,previous]中的列表(因此,current是第一个链接设置不正确的节点)。在每个步骤中,您都要执行以下操作:

  • 记住当前节点的下一个节点,以便可以从该节点继续
  • 将当前链接设置为指向上一个链接,仔细想想,这是正确的方向
  • 将“上一个”更改为“当前”,因为“当前”也正确设置了其链接
  • 将未正确设置链接的第一个节点更改为第一步中记住的节点

如果对所有节点都这样做,则可以证明(例如,使用归纳法)列表将正确反转。

代码只需遍历列表并反转链接,直到它到达前一个尾部,然后返回新的头部

之前:

Node 1 (Head) -> Node 2 -> Node 3 -> Node 4 (Tail) -> null
之后:

   null <- Node 1 (Tail) <- Node 2 <- Node 3 <- Node 4 (Head)
null

我称之为“樱桃采摘”。其想法是尽量减少互换的数量。交换发生在近索引和远索引之间。这是一个twp通行算法

(奇数长度)A->B->C->D->E
(偶数长度)A->B->C->D
先决条件:N>=2
通过1:计数N,元素数
通过2:

对于(j=0->j使用迭代反转单链表:

current = head // Point the current pointer to the head of the linked list

while(current != NULL)
{
    forward = current->link; // Point to the next node
    fforward = forward->link; // Point the next node to next node
    fforward->link = forward; // 1->2->3,,,,,,,,,this will point node 3 to node 2
    forward->link = current; // This will point node 2 to node 1

    if(current == head)
        current->link = NULL; // If the current pointer is the head pointer it should point to NULL while reversing

    current = current->link; // Traversing the list
}
head = current; // Make the current pointer the head pointer

基本思想是将头节点从第一个列表中分离出来,并将其附加到第二个列表的头上。继续重复,直到第一个列表为空

伪代码:

function reverseList(List X) RETURNS List
   Y = null
   WHILE X <> null
      t = X.next
      X.next = Y
      Y = X
      X = t
   ENDWHILE
   RETURN Y
ENDfunction
请注意,helper函数是尾部递归函数。这意味着您可以使用迭代创建复制反转

function reverseList(List X) RETURNS List
   Y = null
   WHILE X <> null
     Y = makeNode(x.data, Y)
     X = X.next   
   ENDWHILE
   RETURN Y
ENDfunction
函数reverseList(列表X)返回列表
Y=null
而X为空
Y=makeNode(x.data,Y)
X=X.next
结束时
返回Y
端功能

单链表反转功能的实现:

struct Node
{
    int data;
    struct Node* link;
}

Node* head = NULL;

void reverseList()
{
    Node* previous, *current, *next;
    previous = NULL;
    current = head;

    while(current != NULL)
    {
        next = current-> link;
        current->link = previous;
        previous = current;
        current = next;
    }

    head = previous;
}

最简单的思考方式是这样想:

  • 首先将列表的标题添加到新的链接列表中
  • 继续迭代原始链接,并在新链接列表的头之前添加节点
  • 图表:

    最初:

    Original List -> 1 2 3 4 5
    New List -> null
    
    第一次迭代

    Original List -> 1 2 3 4 5
    New List -> 1->null [head shifted to left, now newHead contains 1 and points to null]
    
    Original List -> 1 2 3 4 5
    New List -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    Original List -> 1 2 3 4 5
    New List ->3 -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    第二次迭代

    Original List -> 1 2 3 4 5
    New List -> 1->null [head shifted to left, now newHead contains 1 and points to null]
    
    Original List -> 1 2 3 4 5
    New List -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    Original List -> 1 2 3 4 5
    New List ->3 -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    第三次迭代

    Original List -> 1 2 3 4 5
    New List -> 1->null [head shifted to left, now newHead contains 1 and points to null]
    
    Original List -> 1 2 3 4 5
    New List -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    Original List -> 1 2 3 4 5
    New List ->3 -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
    
    现在它一直循环到最后。因此,新列表最终变成:

      New List->  5 -> 4 -> 3 -> 2 -> 1 -> null
    
    相同的代码应如下所示(易于理解):


    下面是一个简单的函数来反转单链表

    // Defining Node structure
    
    
    public class Node {
    int value;
    Node next;
    
    
    public Node(int val) {
        
        this.value=val;
    }
    
    }


    为了更好地理解,你可以观看这段视频

    未来
    导入大括号
    ?我的错..修复为java!1.这段代码似乎不是python…2.列表反转是一个基本算法,你可以在Web上找到许多相关的资料。我会在一张纸上画一个小的三节点链表,然后只需浏览一下算法一步一步,看看会发生什么。你可以在调试器中做同样的事情,但在纸上做会迫使你真正思考每一个状态是如何变化的。Techlead是你吗???我想他想理解“代码”。“反向”的意思很明显,“代码”不是。很好。但是,一个先决条件是我们需要知道链表的长度。是的,这就是为什么它是2次传递的原因。但是第2次传递所需的交换次数总是为什么在任务不是以相反的顺序返回值的列表,而是
    反转链表时分配新的
    ListNode
    ?(为什么不为单个元素列表分配一个新节点?您可以组合特殊情况:
    if(head==null | | head.next==null)return head;
    )@灰胡子是的,可以这样做。但我这样做使它更容易理解,也不占用额外的内存。也许关闭语法突出显示?只有Techlead知道。你怎么知道…xaxa