题源: 206. 反转链表
反转单链表该过程涉及重新指向链表中每个节点的 next
指针,使它们指向前一个节点,而不是下一个节点。
-
初始化指针:
cur
(当前指针):初始化为头结点head
,用于遍历原始链表。pre
(前驱指针):初始化为NULL
,用来逐步构建已经反转部分的链表的头部,并最终成为新的链表头。temp
(临时指针):用于暂存cur
指针的下一个节点,以便cur
移动至下一个节点后,不会失去对链表其余部分的访问。
-
遍历原始链表:
- 使用一个循环,条件为
cur
不为NULL
,即只要当前指针未达到链表尾部,循环就继续。 - 在每次循环迭代中,执行反转操作。
- 使用一个循环,条件为
-
反转操作:
- 使用
temp
保存cur
的下一个节点(cur->next
),这是为了在修改cur->next
指向pre
后,cur
仍能正常移动到下一个节点。 - 将
cur->next
设置为pre
,这是反转的核心步骤,实际上是将当前节点的next
指针指向其前一个节点。 - 更新
pre
为当前节点cur
,即pre
向前移动。 - 将
cur
更新为temp
(即原cur->next
),即cur
向前移动至下一个待处理的节点。
- 使用
-
完成反转:
- 当
cur
变为NULL
,即已经处理完所有节点时,循环结束。 - 此时,
pre
指向新的链表头,因为在最后一次有效的迭代中,cur
指向了链表的最后一个节点,并将其next
指向了前一个节点,pre
随后更新为了这个位置。
- 当
-
返回新的链表头:
- 最终返回
pre
,此时它指向已经完全反转的链表的头部。
- 最终返回
这种方法是反转单链表的经典实现,使用三个指针(cur
, pre
, temp
)来逐步逆转节点间的链接方向,直至整个链表的顺序被反转。整个操作不需要额外的数据结构,仅通过几个指针的简单操作即可完成。
- 空间复杂度为 (O(1))
- 时间复杂度为 (O(n)),其中 (n) 是链表的长度。
Code
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *cur = head;
ListNode *pre = NULL;
ListNode *temp;
while(cur){
temp = cur -> next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};