文章目录
leetcode的相关题目: https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
1 定义
单链表node的数据结构定义如下:
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
2 方式一:就地反转法
2.1 思路
把当前链表的下一个节点pCur插入到头结点dummy的下一个节点中,就地反转。
dummy->1->2->3->4->5的就地反转过程:
dummy->2->1->3->4->5
dummy->3->2->1->4->5
dummy->4>-3->2->1->5
dummy->5->4->3->2->1
2.2 解释
1初始状态
2 过程
pCur是需要反转的节点。
1 prev连接下一次需要反转的节点
2 反转节点pCur
3 纠正头结点dummy的指向
4 pCur指向下一次要反转的节点
1 prev.next = pCur.next;
2 pCur.next = dummy.next;
3 dummy.next = pCur;
4 pCur = prev.next;
2.3 代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL){
return head;
}
ListNode* dummy = new ListNode(-1);
dummy ->next = head;
ListNode* prev = head;
ListNode* pcur = prev -> next;
while(pcur){
prev -> next = pcur -> next;
pcur -> next = dummy -> next;
dummy -> next = pcur;
pcur = prev -> next;
}
pcur = dummy -> next;
//return dummy -> next;
delete dummy; //释放节点,注意!!!
dummy = NULL;
return pcur;
}
};
2.4 总结
1个头结点,2个指针,4行代码
注意初始状态和结束状态,体会中间的图解过程。
3 方式二:新建链表,头节点插入法
3.1 思路
新建一个头结点,遍历原链表,把每个节点用头结点插入到新建链表中。最后,新建的链表就是反转后的链表。
3.2 解释
1 初始状态
2 过程
pCur是要插入到新链表的节点。
pNex是临时保存的pCur的next。
1 pNex保存下一次要插入的节点
2 把pCur插入到dummy中
3 纠正头结点dummy的指向
4 pCur指向下一次要插入的节点
1 pNex = pCur.next
2 pCur.next = dummy.next
3 dummy.next = pCur
4 pCur = pNex
注意:上图有一点问题,网上摘取的
3.3 代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 2.新建链表,头节点插入法
ListNode* dummy = new ListNode(-1);
ListNode* pCur = head;
ListNode* pNex;
while (pCur) {
pNex = pCur -> next;
pCur -> next = dummy -> next;
dummy -> next = pCur;
pCur = pNex;
}
pCur = dummy -> next;
delete dummy;
dummy = NULL;
return pCur;
}
};
3.4 总结
1个头结点,2个指针(包含一个临时保存节点的pNex),4行代码
注意初始状态和结束状态,体会中间的图解过程。