给定单链表的头节点 head,要求反转链表并返回反转后的链表头节点。

核心思路:创建新链表,将原链表中的节点拿来头插
newhead 为 NULLpcur 遍历原链表pcur 的下一个节点(防止丢失后续节点)pcur 插入到新链表头部pcurpcur 到下一个节点pcur 为 NULL 时,返回新链表头节点如图:

struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* newhead,*pcur;
newhead=NULL;
pcur=head;
while(pcur)
{
struct ListNode* tmp=pcur->next;//先保存pcur的下一个节点 头插时会改变pcur的指向
//头插
pcur->next=newhead;
newhead=pcur;
pcur=tmp;
}
return newhead;
}n1:指向已反转部分的最后一个节点(初始为NULL)n2:指向当前待反转节点(初始为头节点)n3:指向下一个待反转节点(初始为头节点的下一个节点)n1 = NULL, n2 = headn3 = head->nextn2 为空: n2 的 next 指针指向 n1(反转当前节点)n1 移动到 n2 位置n2 移动到 n3 位置n3 不为空,则将 n3 移动到下一个节点n1(即新链表的头节点)如图

)
可以看到循环结束的条件是n2为空
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* n1,*n2,*n3;
n1=NULL;
n2=head;
if(n2)//判断链表是否为空
n3=n2->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3)//判断n3是否为空
n3=n3->next;
}
return n1;
}NULLn1 和 n2,再更新 n3n3 前需要检查其是否为空,避免空指针异常方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
头插法 | 逻辑清晰,易于理解 | 需要额外空间存储新链表 | 教学演示,简单场景 |
三指针法 | 原地操作,空间效率高 | 指针操作需要谨慎 | 内存受限环境 |
反转链表是链表操作中的经典问题,2种方法各有特点:
受限环境