手把手写数据结构之单向循环链表操作
1 /**************************头文件***************************/
2
3 #ifndef _LINK_H_
4 #define _LINK_H_
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <time.h>
9
10
11 #define Test(arg) if(arg == NULL){\
12 printf("Invalid arg!\n");\
13 return -1;\
14 }
15
16 /*单链表的实现可以各有不同,只要该实现,符合链表的定义即可。
17 *单链表最重要的数据结构是元素结点,
18 *最重要的操作是插入结点,删除结点和遍历。
19 *其它的操作基本上是这3个操作的组合,依据具体的要求而定。
20 */
21
22 /*切记作为非空循环链表: 恒成立(tail->next == head)*/
23
24 /*******************************************
25 *单向循环链表结点信息
26 *
27 *数据域: 可以是普通类型,也可以是封装类型
28 *指针域: next指针
29 *
30 *********************************************/
31 typedef struct node
32 {
33 int num; //数据域
34 struct node *next; //指针域
35 }NODE;
36
37 /*******************************************
38 *单向循环链表信息
39 *
40 *链表的属性信息: 链表的作用描述,链表当前节点个数等等
41 *指针信息: 一般必须有表头指针,也可以有尾结点指针
42 *
43 *********************************************/
44 typedef struct list_info
45 {
46 int max; //结点个数
47 NODE *head; //头结点指针
48 NODE *tail; //尾结点指针
49 }LIST_INFO;
50
51
52 /*******************************************
53 *Des: 单向循环链表初始化操作,即创建链表
54 *Ret: 成功返回0,失败返回-1
55 *********************************************/
56 int Init_Link(LIST_INFO **plist);
57
58
59 /*******************************************
60 *Des: 判断链表是否为空
61 *Ret: 真空返回1,假空返回0
62 *********************************************/
63 int IS_Empty_Link(LIST_INFO *plist);
64
65 /*******************************************
66 *Des: 清空链表
67 *Ret: 成功返回0, 失败返回-1
68 *********************************************/
69 int Empty_Link(LIST_INFO *plist);
70
71 /*******************************************
72 *Des: 插入结点到表头(与在表尾操作类似)
73 *Ret: 成功返回0,失败返回-1
74 *********************************************/
75 int Insert_to_Head(LIST_INFO *plist, int num);
76
77 /*******************************************
78 *Des: 删除数据域为num的结点
79 *Ret: 成功返回0,失败返回-1
80 *********************************************/
81 int Delete_Node_Num(LIST_INFO *plist, int num);
82
83
84
85 /*******************************************
86 *Des: 销毁链表
87 *Ret: 成功返回0,失败返回-1
88 *********************************************/
89 int Destory_Link(LIST_INFO **plist);
90
91 /*******************************************
92 *Des: 遍历链表
93 *Ret: 成功返回0,失败返回-1
94 *********************************************/
95 int Traverse_Link(LIST_INFO *plist);
96
97 #endif
98
99
100
101 /*************************循环链表API接口函数实现*************************/
102
103
104 #include "sc_link.h"
105
106 /*******************************************
107 *Des: 创建结点
108 *Ret: 成功返回结点,失败返回NULL
109 *********************************************/
110 static NODE *__Create_Node__(int num)
111 {
112 NODE *new_node = (NODE *)malloc(sizeof(NODE));
113 if(NULL == new_node)
114 {
115 perror("Create Node");
116 return NULL;
117 }
118
119 new_node->next = NULL;
120 new_node->num = num;
121
122 return new_node;
123 }
124
125
126 /*******************************************
127 *Des: 单向循环链表初始化操作,即创建链表
128 *Ret: 成功返回0,失败返回-1
129 *********************************************/
130 int Init_Link(LIST_INFO ** plist)
131 {
132 Test(plist);//参数有效性检测
133
134 //创建链表
135 *plist = (LIST_INFO *)malloc(sizeof(LIST_INFO));
136 if(NULL == *plist)
137 {
138 perror("Create List");
139 return -1;
140 }
141
142 //初始化链表
143 (*plist)->head = (*plist)->tail = NULL;
144 (*plist)->max = 0;
145
146 return 0;
147 }
148
149 /*******************************************
150 *Des: 判断链表是否为空
151 *Ret: 真空返回1,假空返回0
152 *********************************************/
153 int IS_Empty_Link(LIST_INFO *plist)
154 {
155 return (NULL == plist->head);
156 }
157
158 /*******************************************
159 *Des: 清空链表
160 *Ret: 成功返回0, 失败返回-1
161 *********************************************/
162 int Empty_Link(LIST_INFO *plist)
163 {
164 Test(plist);//参数有效性检测
165
166 //判断是否已经为空
167 if(IS_Empty_Link(plist))
168 {
169 printf("The list is empty!\n");
170 return -1;
171 }
172
173 NODE *fnode = NULL, *pnode = plist->head;
174 while(plist->tail != pnode)
175 {
176 fnode = pnode;
177 pnode = pnode->next;
178 free(fnode);
179 }
180 fnode = plist->tail;
181 free(fnode);
182
183 plist->head = plist->tail = NULL;
184 plist->max = 0;
185
186 return 0;
187 }
188
189 /*******************************************
190 *Des: 销毁链表
191 *Ret: 成功返回0,失败返回-1
192 *********************************************/
193 int Destory_Link(LIST_INFO **plist)
194 {
195 Test(plist);//函数入口检测
196
197 //清空链表
198 if(Empty_Link(*plist) < 0)
199 return -1;
200
201 free(*plist);
202
203 *plist = NULL;
204
205 return 0;
206 }
207
208
209
210 /*******************************************
211 *Des: 插入结点到表头(与在表尾操作类似)
212 *Ret: 成功返回0,失败返回-1
213 *********************************************/
214 int Insert_to_Head(LIST_INFO *plist, int num)
215 {
216 Test(plist);//参数有效性检测
217
218 NODE *new_node = __Create_Node__(num);
219 if(NULL == new_node)
220 return -1;
221
222 if(IS_Empty_Link(plist))//当链表为空
223 {
224 plist->head = plist->tail = new_node;
225 plist->head->next = plist->tail;
226 plist->tail->next = plist->head;
227 }
228 else
229 {
230 plist->tail->next = new_node;
231 new_node->next = plist->head;
232 plist->head = new_node;
233 }
234
235 plist->max++;
236
237 return 0;
238 }
239
240 /*******************************************
241 *Des: 删除数据域为num的结点
242 *Ret: 成功返回0,失败返回-1
243 *********************************************/
244 int Delete_Node_Num(LIST_INFO *plist, int num)
245 {
246 Test(plist);
247
248 NODE *fnode = NULL, *tmpnode = NULL, *pnode = NULL;
249
250 //判断链表是否为空
251 if(IS_Empty_Link(plist))
252 {
253 printf("The list is empty!\n");
254 return -1;
255 }
256
257 //查找结点是否有符合的
258 pnode = plist->head;
259 while(pnode != plist->tail)
260 {
261 if(pnode->num == num)
262 break;
263 tmpnode = pnode;
264 pnode = pnode->next;
265 }
266 if(pnode == plist->tail)//结束条件为到了链表的尽头
267 {
268 if(pnode->num == num)//如果尾结点是的
269 {
270 fnode = pnode;
271 if(plist->max == 1)//只有一个节点
272 {
273 plist->head = plist->tail = NULL;
274 }
275 else
276 {
277 tmpnode->next = plist->head;
278 plist->tail = tmpnode;
279 }
280 }
281 else
282 {
283 printf("Have no such Node!\n");
284 return -1;
285 }
286 }
287 else//循环条件因为找到符合的结点而结束的
288 {
289 if(NULL == tmpnode)//如果是头结点
290 {
291 fnode = plist->head;
292 plist->tail->next = fnode->next;
293 plist->head = fnode->next;
294 }
295 else
296 {
297 fnode = tmpnode->next;
298 tmpnode->next = fnode->next;
299 }
300 }
301
302 free(fnode);
303 plist->max--;
304
305 return 0;
306 }
307
308 /*******************************************
309 *Des: 遍历链表
310 *Ret: 成功返回0,失败返回-1
311 *********************************************/
312 int Traverse_Link(LIST_INFO *plist)
313 {
314 Test(plist);//参数有效性检测
315
316 if(IS_Empty_Link(plist))//判断链表是否为空
317 {
318 printf("The list is empty!\n");
319 return -1;
320 }
321
322 printf("The count of Node: %d\n", plist->max);
323 NODE *pnode = plist->head;
324 while(pnode != plist->tail)
325 {
326 printf("%-5d", pnode->num);
327 pnode =pnode->next;
328 }
329 printf("%-5d", pnode->num);
330
331 printf("\n\n");
332
333 return 0;
334 }
335
336
337
338 /**************************测试代码***************************/
339
340 #include "sc_link.h"
341 #define RANDOM rand()%10
342
343 int main()
344 {
345
346 srand(time(NULL));
347
348 int i, num;
349 LIST_INFO *plist = NULL;
350
351 //初始化链表操作
352 Init_Link(&plist);
353
354 //添加结点
355 //for(i = 0; i < 5; i++)
356 //{
357 // num = RANDOM;
358 // printf("%5d", num);
359 Insert_to_Head(plist, 8);
360 //}
361 printf("\n\n");
362
363 Traverse_Link(plist);
364
365 //清空链表操作
366 //Empty_Link(plist);
367
368 Delete_Node_Num(plist, 8);
369
370 Traverse_Link(plist);
371
372 return 0;
373 }