题目描述
思路一:循环迭代
链表关键是靠指针链接的,因此反转链表的本质就是改变指针的指向关系
初始状态
我们先尝试分析一下1和2之间的指针方向如何改变
先定义两个变量,n1开始时空指针,n2指向了第一个节点,其实只需要一句代码,n2->next = n1,就可以断开1,2链接,形成如图所示链接
循环迭代
接下来肯定要改变后面的指针指向了,而且思路与初识状态是一样的,因此关键就是n1和n2迭代往后走,但是n2此时还能找到后面的节点吗?显然不能,因为1,2之间的链接已经断开了,所以我们需要额外定义一个指针变量n3来保存下一个节点地址
核心逻辑: n2->next = n1
这就是这道题的整体思路,显然需要写一个while循环。
易错点便是while循环结束条件,一定要注意,结束条件不是n3为空,而是n2为空
如果写while(n3),则最后状态如下:
循环已经结束了,但是最后一个箭头还没有翻转过来(因为每次进入循环先翻转箭头,再迭代往后走)
因此循环结束条件是while(n2)
但是这样提交后明显出现了问题
错误显示n3=n3->next产生了空指针解引用报错
n3目前为空,循环还未结束,因此进入循环,其中n3=n3->next便会报错
因此我们应该加上一个判断语句:if(n3) n3 = n3->next
正确代码:
struct ListNode* reverseList(struct ListNode* head) {
if(head == NULL)
return NULL;
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = head->next;
while (n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3)
n3 = n3->next;
}
return n1;
}
思路二:头插
逻辑很简单,在单链表相关操作中已经详细介绍过头插操作(注意保存下一个节点地址即可)
正确代码
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* newhead = NULL;
struct ListNode* cur = head;
struct ListNode* tmp = head;
while(cur)
{
tmp = cur->next;
cur->next = newhead;
newhead = cur;
cur = tmp;
}
return newhead;
}
本文关于反转链表的介绍就到这里了,文章仍有许多不足,欢迎大家交流指正~~~