反转链表题解
题目:
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表。示例 1:
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
思路:
使用迭代法反转单链表,通过三个指针(
pre
、cur
、tmp
)在遍历链表的过程中逐步反转节点的指向关系。核心思想是:
保存下一个节点:在修改当前节点的
next
指针前,先保存它的原始下一个节点反转指针:将当前节点的
next
指针指向前一个节点移动指针:将
pre
和cur
指针向前移动,继续处理下一个节点终止条件:当
cur
为NULL时,表示所有节点都已处理完毕
代码:
struct ListNode* reverseList(struct ListNode* head)
{
// 当前节点指针,初始指向链表头
struct ListNode* cur = head;
// 前驱节点指针,初始为NULL(因为反转后的链表尾应该指向NULL)
struct ListNode* pre = NULL;
// 遍历链表直到当前节点为空
while(cur != NULL)
{
// 临时保存当前节点的下一个节点
// 因为在修改cur->next后会丢失原始的下一个节点信息
struct ListNode * tmp = cur->next;
// 反转操作:将当前节点的next指针指向前一个节点
cur->next = pre;
// 前驱指针向前移动:pre移动到当前节点位置
pre = cur;
// 当前指针向前移动:cur移动到之前保存的下一个节点位置
cur = tmp;
}
// 循环结束时,pre指向原链表的最后一个节点,即新链表的头节点
return pre;
}
代码分析:
关键步骤说明
指针初始化:
cur
初始化为head
,表示从链表头开始处理
pre
初始化为NULL
,因为反转后的链表尾应该指向NULL
循环中的四步操作:
保存next节点:
tmp = cur->next
(防止修改指针后丢失信息)反转指针:
cur->next = pre
(改变当前节点的指向)移动pre指针:
pre = cur
(pre前进到当前节点位置)移动cur指针:
cur = tmp
(cur前进到下一个待处理节点)终止条件:
当
cur
为NULL
时,表示所有节点都已处理完毕返回值:
pre
最终指向原链表的最后一个节点,即反转后新链表的头节点示例演示
以链表 1 → 2 → 3 → NULL 为例:
初始状态:
cur: 1 → 2 → 3 → NULL
pre: NULL
第一次循环后:
链表:1 → NULL
pre: 1 → NULL
cur: 2 → 3 → NULL
第二次循环后:
链表:2 → 1 → NULL
pre: 2 → 1 → NULL
cur: 3 → NULL
第三次循环后:
链表:3 → 2 → 1 → NULL
pre: 3 → 2 → 1 → NULL
cur: NULL
最终返回
pre
(3),得到反转后的链表 3 → 2 → 1 → NULL