leetcode力扣 206https://leetcode.cn/problems/reverse-linked-list/description/
题目:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例:
1.建立虚拟头结点辅助,实现反转
先建立一个虚拟结点dummy。然后将原链表上的结点一个一个接在dummy后面,最后返回dummy->next 。下面看画图演示
ListNode* reverseList(ListNode* head) {
if(head==NULL) return NULL;
//虚拟头结点
ListNode* dummy=new ListNode(-1,NULL);
ListNode* cur=head;
ListNode* next=NULL;
while(cur!=NULL){
next=cur->next;
cur->next=dummy->next;
dummy->next=cur;
cur=next;
}
cur=dummy->next;
delete dummy;
return cur;
}
2.直接操作链表实现反转
还可以不使用虚拟结点,直接在链表上操作,创建3个指针pre,cur,next,分别指向该结点的前一个结点,当前结点和当前结点的后一个结点,然后按照顺序一个一个操作,下面看图,注意箭头的指向
观察发现如下:反转前后其实就是箭头逆向了而已,我们就一个一个修改箭头就行了
ListNode* reverseList(ListNode* head) {
if(head==NULL) return NULL;
ListNode* cur=head;
ListNode* pre=NULL;
ListNode* next=NULL;
while(cur!=NULL){
next=cur->next;
//修改箭头方向,即cur的next域
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
3.使用递归实现反转
使用递归实现会比较难以理解,但其本质其实与第二种方法差不多,就是修改箭头的方向,但是是从最后开始修改的
我们可以发现其实对于要修改next域的结点的前一个结点而已,操作其实就是cur->next->next=cur;
ListNode* reverseList(ListNode* head) {
if(head==NULL||head->next==NULL) return head;
ListNode* cur=head;
ListNode* newHead=reverseList(cur->next);
cur->next->next=cur;
cur->next=NULL;
return newHead;
}