反转单链表@Leetcode--链表
Posted 呀小边同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反转单链表@Leetcode--链表相关的知识,希望对你有一定的参考价值。
题目
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
//Definition for singly-linked list:
struct ListNode {
int val;
struct ListNode *next;
};
函数接口:
struct ListNode* reverseList(struct ListNode* head){
}
反转一个单链表: OJ链接
思路一:
改变“箭头”指向
❄️反转?
显然我们需要两个指针来负责反转(n1
,n2
),然而在反转的同时(n2->next = n1;
),原本①和②之间的链接也断开了,这我们就需要第三个指针来记录下一个节点的位置(n3
)
因此,我们定义了如下三个指针并初始化
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;
struct ListNode* n3 = head->next;
其中,n1
,n2
负责反转,n3
负责记录。
n2->next = n1;//反转
❄️ 迭代向后挪动?
挪动过程:
可以很轻易的写出代码:
n1 = n2;
n2 = n3;
n3 = n3->next;
❄️ 终止条件?
快进~
因此在n2->next==NULL
时,循环结束(注意,循环括号内,想的是终止条件,写的是进行条件)。
while (n2 != NULL)
{
//翻转
n2->next = n1;
//迭代向后挪
n1 = n2;
n2 = n3;
n3 = n3->next;
}
细心的小伙伴可能已经发现了,在这一次反转之后的迭代挪动中,n3 = n3->next;
是对空指针的解引用😱,会崩掉,不过没关系啦,做一下处理就好了!
if(n3 != NULL)
n3 = n3->next;
看图!此时,我们要返回链表的头结点为n1
这里给出完整代码:
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL)
{
return NULL;//处理空链表
}
//初始条件
struct ListNode* n1 = NULL;
struct ListNode* n2 = head;//n1,n2用来交换
struct ListNode* n3 = head->next;//n3用来记录下一个
while(n2!=NULL)
{
//翻转
n2->next = n1;
//迭代向后挪
n1 = n2;
n2 = n3;
if(n3)
n3 = n3->next;
}
return n1;
}
思路二:
🔑 取原链表节点,头插到
newhead
新链表中去
有过思路一的详细铺垫,思路二分析起来就很简单咯!
定义指针并初始化:
struct ListNode* cur = head;
struct ListNode* next = head->next;
struct ListNode* newhead = NULL;//新链表的头
❄️头插
//头插
cur->next = newhead;
newhead = cur;
❄️ 迭代挪动
❄️终止条件
快进~
while (cur != NULL)
{
//头插
cur->next = newhead;
newhead = cur;
//迭代往后挪
cur = next;
if (next)
next = next->next;
}
给出完整代码:
struct ListNode* reverseList(struct ListNode* head){
if(head == NULL)
{
return head;//处理空链表
}
//初始化
struct ListNode* cur = head;
struct ListNode* next = head->next;
struct ListNode* newhead = NULL;//新链表的头
while(cur!=NULL)
{
//头插
cur->next = newhead;
newhead = cur;
//迭代往后挪
cur = next;
if(next)
next = next->next;
}
return newhead;
}
那么下面这样写也是可的,而且这里不需要再处理空链表,也无需处理next = next->next;
在末尾会发生空指针的解引用问题。
这是由于迭代写法上有一点点的小改变(struct ListNode* next = cur->next;
),且写在了while循环的内部。
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* cur = head;
struct ListNode* newhead = NULL;//新链表的头
while(cur)
{
struct ListNode* next = cur->next;
//头插
cur->next = newhead;
newhead = cur;
//迭代向后挪
cur = next;
}
return newhead;
}
本题完@边通书
以上是关于反转单链表@Leetcode--链表的主要内容,如果未能解决你的问题,请参考以下文章