什么是复杂链表?
复杂链表指的是一个链表有若干个结点,每个结点有一个数据域用于存放数据,还有两个指针域,其中一个指向下一个节点,还有一个随机指向当前复杂链表中的任意一个节点或者是一个空结点。今天我们要实现的就是对这样一个复杂链表复制产生一个新的复杂链表。
复杂链表的数据结构如下:
1 typedef int DataType; //数据域的类型2
3 //复杂链表的数据结构
4
5 typedef structComplexNode6
7 {8
9 DataType _data ; //数据
10
11 struct ComplexNode * _next; //指向下个节点的指针
12
13 struct ComplexNode * _random; //指向随机节点(可以是链表中的任意节点 or 空)
14
15 }ComplexNode;
上图就是一个复杂链表的例子,那么我们应该如何实现复杂链表的复制呢?
1、首先我们应该根据已有的复杂链表创建一条新的复杂链表,但是这个新的复杂链表的所有的结点的random指针都指向空,这样是很好实现的,相当于我们创建了一条简单的单链表(newlist),我们要复制的链表不妨称之为oldlist。
2、接下来我们应该把新创建的这条复杂链表(newlist)与已有的复杂链表(oldlist)合并成如下的形式:
在这种情况下我们已经把两条复杂链表合并成了一条链表(称之为linklist),通过对这条链表(linklist)的观察,我们可以发现合并的链表(linklist)中属于newlist的结点pnew的上一个结点pold(属于oldlist的结点)的random指针所指向的结点的next指针就应该是pnew结点的randow指针所指向的结点。
这样我们让pold和pnew指针一直往后走最后就可以实现对所有属于新创建的复杂链表(newlist)的random指针指向相应的结点的操作。构成的复杂链表如下图
在完成以上的步骤之后我们所要做的工作就很简单了,我们只要把这一条链表linklist分开成我们的newlist链表和oldlist链表就可以了。
这样我们就完美的完成了复杂链表的复制工作下面就是具体实现的代码:
头文件complexnode.h:
1 #ifndef __COMPLEX__NODE__H__2
3 #define __COMPLEX__NODE__H__
4
5
6
7 //包含头文件
8
9 #include
10
11 #include
12
13 #include
14
15
16
17
18
19 typedef int DataType; //数据域的类型20
21
22
23 //复杂链表的数据结构
24
25 typedef structComplexNode26
27 {28
29 DataType _data ; //数据
30
31 struct ComplexNode * _next; //指向下个节点的指针
32
33 struct ComplexNode * _random; //指向随机节点(可以是链表中的任意节点 or 空)
34
35 }ComplexNode;36
37
38
39 //创建一个复杂链表的结点
40
41 ComplexNode *BuyComplexNode(DataType x);42
43
44
45 //打印复杂的单链表
46
47 void Display(const ComplexNode *cplist);48
49
50
51 //复杂链表的复制
52
53 ComplexNode * CopyComplexNode(ComplexNode *cplist);54
55
56
57 #endif//__COMPLEX__NODE__H__
具体功能实现complexnode.c
1 #include "complexnode.h"
2
3
4
5 //创建一个复杂链表的结点
6
7 ComplexNode *BuyComplexNode(DataType x)8
9 {10
11 ComplexNode *cnode = (ComplexNode *)malloc(sizeof(ComplexNode));12
13 if(cnode == NULL)//创建失败
14
15 {16
17 perror("BuyComplexNode()::malloc");18
19 returnNULL;20
21 }22
23 //创建成功
24
25 cnode->_data =x;26
27 cnode->_next =NULL;28
29 cnode->_random =NULL;30
31 returncnode;32
33 }34
35
36
37 //打印复杂的单链表
38
39 void Display(const ComplexNode *cplist)40
41 {42
43 ComplexNode *pnode =cplist;44
45 while(pnode)46
47 {48
49 printf("%d::%d -->",pnode->_data,pnode->_random->_data);50
51 pnode = pnode->_next;52
53 }54
55 printf("over\n");56
57
58
59 }60
61
62
63 //复杂链表的复制
64
65 ComplexNode * CopyComplexNode(ComplexNode *cplist)66
67 {68
69
70
71 ComplexNode * pold =NULL;72
73 ComplexNode * pnew =NULL;74
75 ComplexNode * newlist = NULL;//指向新的复杂链表的头结点的指针
76
77 pold =cplist;78
79 //创建一条新的复杂链表
80
81 while(pold !=NULL)82
83 {84
85 ComplexNode * new_node = BuyComplexNode(pold->_data);86
87 if(newlist == NULL)//当新的复杂链表中没有结点时
88
89 {90
91 newlist =new_node;92
93 }94
95 else//当新的复杂链表有结点时
96
97 {98
99 ComplexNode * node =newlist;100
101 while(node->_next != NULL)//找到最后一个结点
102
103 {104
105 node = node->_next;106
107 }108
109 node->_next = new_node;//插入新的结点
110
111 }112
113 pold = pold->_next;114
115
116
117 }//创建新的复杂链表结束118
119
120
121 //合并两条复杂链表
122
123 pold =cplist;124
125 pnew =newlist;126
127 while(pold)128
129 {130
131 ComplexNode * curold =NULL;132
133 ComplexNode * curnew =NULL;134
135 curold = pold->_next;136
137 curnew = pnew->_next;138
139 if(pold->_next ==NULL)140
141 {142
143 pold->_next =pnew;144
145 pold =curold;146
147 pnew =curnew;148
149 break;150
151 }152
153 pold->_next =pnew;154
155 pnew->_next =curold;156
157 pold =curold;158
159 pnew =curnew;160
161 }//合并两条复杂链表结束162
163
164
165 //让新创建的那条复杂链表上的所有结点的random指针指向相应的结点
166
167 pold =cplist;168
169 pnew =newlist;170
171 while(pnew)172
173 {174
175 pnew->_random = pold->_random->_next;176
177 pold = pnew->_next;178
179 if(pold == NULL)//这是pnew的_next指针已经指向空
180
181 {182
183 break;184
185 }186
187 pnew = pold->_next;188
189 }//结束190
191
192
193 //分离合并后的复杂链表
194
195 pold =cplist;196
197 pnew =newlist;198
199 while(pold)200
201 {202
203 ComplexNode * curold =NULL;204
205 ComplexNode * curnew =NULL;206
207 if(pnew->_next == NULL)//已经分离完成
208
209 {210
211 pold->_next =NULL;212
213 pnew->_next =NULL;214
215 break;216
217
218
219 }220
221 curold = pold->_next->_next;222
223 curnew = pnew->_next->_next;224
225
226
227 pold->_next =curold;228
229 pnew->_next =curnew;230
231 pold =curold;232
233 pnew =curnew;234
235 }//分离合并的复杂链表结束
236
237
238
239 returnnewlist;240
241 }
测试代码test.c:
1 #include "complexnode.h"
2
3 //
4
5 //复杂链表的复制。?个链表的每个节点,有?个指向next指针指向下?个节6
7 //点,还有?个random指针指向这个链表中的?个随机节点或者NULL,现在要8
9 //求实现复制这个链表,返回复制后的新链表。10
11 //ps: 复杂链表的结构
12
13
14
15
16
17
18
19 voidtest()20
21 {22
23 ComplexNode *cplist;24
25 ComplexNode *copylist;26
27 ComplexNode *node1;28
29 ComplexNode *node2;30
31 ComplexNode *node3;32
33 ComplexNode *node4;34
35 cplist = BuyComplexNode(1);36
37 node1 = BuyComplexNode(2);38
39 node2 = BuyComplexNode(3);40
41 node3 = BuyComplexNode(4);42
43 node4 = BuyComplexNode(5);44
45 cplist->_next =node1;46
47 node1->_next =node2;48
49 node2->_next =node3;50
51 node3->_next =node4;52
53 cplist->_random =node3;54
55 node1->_random =node4;56
57 node2->_random =cplist;58
59 node3->_random =node1;60
61 node4->_random =node2;62
63 Display(cplist);64
65 copylist =CopyComplexNode(cplist);66
67 Display(copylist);68
69
70
71 }72
73 intmain()74
75 {76
77 test();78
79 return 0;80
81 }
程序的运行结果如下图:
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有