数据结构:单链表就地逆置(递归方法)解析

先上代码:

 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;

 以上。

 

posted @ 2018-06-16 17:20  Hwangzhiyoung  阅读(5690)  评论(2编辑  收藏  举报