先上代碼:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 struct ListNode { 6 int value; 7 ListNode *next; 8 ListNode(int x) :value(x), next(NULL) {} 9 }; 10 11 //單鏈表的轉置 12 // 1)遞歸方法 13 ListNode* reverseByRecursion(ListNode *head) 14 { 15 if (head == NULL || head->next == NULL) 16 return head; 17 ListNode *newhead = reverseByRecursion(head->next); 18 19 head->next->next = head; 20 head->next = NULL; 21 return newhead; 22 } 23 24 int main() { 25 ListNode a(3); 26 ListNode b(1); 27 ListNode c(5); 28 ListNode d(6); 29 ListNode e(2); 30 a.next = &b; 31 b.next = &c; 32 c.next = &d; 33 d.next = &e; 34 ListNode *head = &a; 35 ListNode* newhead = reverseByRecursion(head); 36 while (newhead != NULL) { 37 printf("%d\n", newhead->value); 38 newhead = newhead->next; 39 } 40 system("pause"); 41 }
強烈建議用visual studio,特別是在用到遞歸的時候,程序什么時候返回,返回到哪里,指針指向的內容會比較難以弄清,但是單步調試就解決了這個問題。
首先定義一個鏈表:
1 struct ListNode{ 2 int value; 3 ListNode *next; 4 ListNode(int x):value(x),next(NULL){} 5 };
然后把它們給串聯起來形成一個鏈表:
1 ListNode a(3); 2 ListNode b(1); 3 ListNode c(5); 4 ListNode d(6); 5 ListNode e(2); 6 a.next = &b; 7 b.next = &c; 8 c.next = &d; 9 d.next = &e;
接着就是進行遞歸調用,從最后一個節點開始,每每兩個節點進行就地逆置,這里要搞明白什么是淺拷貝,
淺拷貝的意思就是只復制引用(指針),而未復制真正的值。
所以newhead的處理流程是這樣的,
2->6 2->6->5 2->6->5->1 2->6->5->1->3
每次兩兩就地逆置的時候,會關聯前面的上下文。
下面幾行的代碼不清楚的地方就用單步調試去運行,會有收獲的。搞清楚每個節點都相對應的內存空間,我們要做的事只是重新對這些節點進行排序。
1 ListNode *newhead = reverseByRecursion(head->next); 2 3 head->next->next = head; 4 head->next = NULL; 5 return newhead;
以上。
