數據結構:單鏈表就地逆置(遞歸方法)解析


先上代碼:

 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;

 以上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM