力扣题目206:反转链表
对上述链表进行反转后为:
反转过程即改变各个结点指针域(next)的指向。
1)双指针法
首先初始化三个结点,pre指向NULL;cur指向head;temp可以先不指向(因为后续调整next指向时需要用其来保存下一个结点)。
循环中,如果cur指向不为NULL,则继续循环。首先将cur的下一个结点2保存至temp中,cur指向结点1的指针域指向改为pre(NULL),然后将pre更新至cur处(保存前一个结点,下次循环中使用)。最后将cur进行更新为temp。
继续循环(cur指向结点2,不为NULL),结点3保存至temp中,cur(结点2)的指针域指向pre,pre更新为cur当前值(结点2),cur更新为temp,进行下次循环。
其余结点同理。cur为NULL时,反转完成,循环结束。当前链表的头结点为pre所保存的值,即为结点5。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {//双指针法
ListNode* cur = head;
ListNode* pre = nullptr;
ListNode* temp;
while (cur) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
2)递归法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverse(ListNode* pre, ListNode* cur){
if (cur == nullptr)
return pre;//即为最后的头结点
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
return reverse(pre,temp);
}
ListNode* reverseList(ListNode* head) {//递归法
return reverse(nullptr,head);
}
};
递归法的实现与双指针的基本逻辑是一样的,如果当前指向的是NULL了,则代表已经反转完成了,返回当前的pre(反转后的头结点)。
否则进行反转操作,即更新各结点的next。然后继续递归调用reverse反转下个结点。