![](https://img-blog.csdnimg.cn/img_convert/ff917e2807c6bf1ca8deb07cc4f74bf7.png)
我们有两种思路。
法一:三指针法,我们用n1,n2,n3三个指针,n1指向没反转的头,n2指向n1的next,n3指向n2的next。
![](https://img-blog.csdnimg.cn/img_convert/d56906f9261a0b4a0ce3acbed0d154c5.png)
![](https://img-blog.csdnimg.cn/img_convert/cc7e3f4fd89359d28f287c4d99922d18.png)
然后n1->next = NULL;表示反转后的尾。
![](https://img-blog.csdnimg.cn/img_convert/213c6259272925b89df43a7057132482.png)
接着每次取n2的节点对n1进行头插,然后往下走,一直走到n2为空时,循环结束,此时也反转完成,此时的n1指向的是反转后链表的头,返回n1即可。
![](https://img-blog.csdnimg.cn/img_convert/6f46bec329bd9c59686ce7e4e54138fd.png)
![](https://img-blog.csdnimg.cn/img_convert/be6b9e00a5f857186954b1ec2ed42f7f.png)
![](https://img-blog.csdnimg.cn/img_convert/b4d6db8850af9f78eb04cc6b9af4d64a.png)
![](https://img-blog.csdnimg.cn/img_convert/aa04e84955d946986f9d9e4c62e0310f.png)
n2会指向空是因为原链表的结尾是null,这里要注意,当n2指向空时,n3会变成野指针,所以为了避免这种情况,我们可以加一个判断n3的下一个节点是否为空,不为空就往下走。下面我们看看代码实现。
struct ListNode* reverseList(struct ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
struct ListNode* n1, *n2, *n3;
n1 = head;
n2 = n1->next;
n3 = n2->next;
n1->next = NULL;
//中间节点不为空,继续修改指向
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;
while(cur)
{
struct ListNode* next = cur->next;
//头插新节点,更新头
cur->next = newhead;
newhead = cur;
cur = next;
}
return newhead;
}