對單鏈表進行反轉有迭代法和遞歸法兩種。
1. 迭代法
- 迭代法從前往后遍歷鏈表,定義三個指針分別指向相鄰的三個結點,反轉前兩個結點,即讓第二個結點指向第一個結點。然后依次往后移動指針,直到第二個結點為空結束,再處理鏈表頭尾即可。
/**
* 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 || head->next == NULL) // 空鏈或只有一個結點,直接返回頭指針
{
return head;
}
else // 至少有兩個結點
{
ListNode * p1 = head; // 第一個結點
ListNode * p2 = p1->next; // 第二個結點
ListNode * p3 = p2->next; // 第三個結點
while (p2) // 第二個結點為空,到鏈尾,結束
{
p3 = p2->next;
p2->next = p1; // 第二個結點指向第一個結點,進行反轉
p1 = p2; // 第一個結點往后移
p2 = p3; // 第二個結點往后移
}
head->next = NULL; // 第一個結點也就是反轉后的最后一個節點指向 NULL
head = p1; // 頭結點指向反轉后的第一個節點
return head;
}
}
};
2. 遞歸法
- 基線條件:空鏈或只有一個結點,直接返回頭指針
- 遞歸條件:遞歸調用,返回子鏈表反轉后的頭指針
Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) // 空鏈或只有一個結點,直接返回頭指針
{
return head;
}
else // 有兩個以上結點
{
ListNode *new_head = reverseList(head->next); // 反轉以第二個結點為頭的子鏈表
// head->next 此時指向子鏈表的最后一個結點
// 將之前的頭結點放入子鏈尾
head->next->next = head;
head->next = NULL;
return new_head;
}
}
};
獲取更多精彩,請關注「seniusen」!