目录
- 使用虚拟头节点来辅助实现链表反转
- 直接操作链表实现反转
- 使用递归来实现链表反转
链表是计算机科学中常用的数据结构之一,它由一系列节点构成,每个节点包含一个值和指向下一个节点的指针。链表的灵活性使其在许多场景下被广泛应用,但其中的一个常见问题是如何反转链表。我们来了解下面两种实现链表反转的方法。
使用虚拟头节点来辅助实现链表反转
首先我们先来建立一个虚拟节点dummyNode,并且使dummyNode.next=head,这样就可以很好的简化我们的操作。
public ListNode reverseList(ListNode head) {
ListNode dummyNode = new ListNode(-1);
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = dummyNode.next;
dummyNode.next = cur;
cur = next;
}
return dummyNode.next;
}
在循环体中,首先将cur.next赋值给next,用于保存cur的下一个节点。然后将dummyNode.next赋值给cur.next,即将cur与dummyNode相连,形成一个新的链表。接着将cur赋值给dummyNode.next,即将dummyNode与下一个节点相连。最后将next赋值给cur,继续遍历链表。
直接操作链表实现反转
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
方法内部定义了两个变量pre和cur,分别表示当前节点的前一个节点和当前节点。初始时,pre为null,cur为head。
接下来是一个while循环,当cur不为null时,循环继续执行。在循环内部,首先将cur的下一个节点赋值给next,然后将cur的next指针指向pre,即将当前节点cur与前一个节点pre相连。接着将pre赋值给cur,表示当前节点变为前一个节点。最后将next赋值给cur,表示将当前节点更新为下一个节点。
循环结束后,pre即为反转后的链表头节点,返回pre即可。
使用递归来实现链表反转
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
- 首先判断链表是否为空或只有一个节点,如果是,则直接返回head,因为不需要反转。
- 如果链表有多个节点,递归调用reverseList(head.next),将链表的剩余部分反转,并将新的头节点赋值给newHead。
- 接下来,将原链表的尾节点与新链表的头部相连,即将head.next.next指向head。
- 将原链表的尾节点置为null,表示已经处理完毕。
- 最后返回新的头节点newHead。