手把手写数据结构之单向链表操作(二)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4
5
6 #define Test(arg) if(arg == NULL){\
7 printf("Invalid arg!\n");\
8 return -1;\
9 }
10
11 /*单链表的实现可以各有不同,只要该实现,符合链表的定义即可。
12 *单链表最重要的数据结构是元素结点,
13 *最重要的操作是插入结点,删除结点和遍历。
14 *其它的操作基本上是这3个操作的组合,依据具体的要求而定。
15 */
16
17 /*******************************************
18 *单向链表结点信息
19 *
20 *数据域: 可以是普通类型,也可以是封装类型
21 *指针域: next指针
22 *
23 *********************************************/
24 typedef struct node
25 {
26 int num; //数据域
27 struct node *next; //指针域
28 }NODE;
29
30 /*******************************************
31 *单向链表信息
32 *
33 *链表的属性信息: 链表的作用描述,链表当前节点个数等等
34 *指针信息: 一般必须有表头指针,也可以有尾结点指针
35 *
36 *********************************************/
37 typedef struct list_info
38 {
39 int max; //结点个数
40 NODE *head; //头结点指针
41 NODE *tail; //尾结点指针
42 }LIST_INFO;
43
44
45
46
47
48 /*******************************************
49 *Des: 单向链表初始化操作,即创建链表
50 *Ret: 成功返回0,失败返回-1
51 *********************************************/
52 static NODE *__Create_Node__(int num)
53 {
54 NODE *new_node = (NODE *)malloc(sizeof(NODE));
55 if(NULL == new_node)
56 {
57 perror("Create Node");
58 return NULL;
59 }
60
61 new_node->next = NULL;
62 new_node->num = num;
63
64 return new_node;
65 }
66
67 /*******************************************
68 *Des: 单向链表初始化操作,即创建链表
69 *Ret: 成功返回0,失败返回-1
70 *********************************************/
71 int Init_Link(LIST_INFO **plist)
72 {
73 Test(plist);//函数入口检测
74
75 *plist = (LIST_INFO *)malloc(sizeof(LIST_INFO));
76 if(NULL == *plist)
77 {
78 perror("Create List");
79 return -1;
80 }
81
82 (*plist)->head = NULL;
83 (*plist)->tail = NULL;
84 (*plist)->max = 0;
85
86 return 0;
87 }
88
89
90 /*******************************************
91 *Des: 判断链表是否为空
92 *Ret: 真空返回1,假空返回0
93 *********************************************/
94 int IS_Empty_Link(LIST_INFO *plist)
95 {
96 return (NULL == plist->head) ? 1 : 0;
97 }
98
99 /*******************************************
100 *Des: 清空链表
101 *Ret: 成功返回0, 失败返回-1
102 *********************************************/
103 int Empty_Link(LIST_INFO *plist)
104 {
105 Test(plist);//函数入口检测
106
107 NODE *fnode, *pnode = plist->head;
108 if(IS_Empty_Link(plist))
109 {
110 printf("The list is already empty!\n");
111 return -1;
112 }
113
114 while(NULL != pnode)
115 {
116 fnode = pnode;
117 pnode = pnode->next;
118 free(fnode);
119 }
120
121 plist->head = plist->tail = NULL;
122 plist->max = 0;
123
124 return 0;
125 }
126
127 /*******************************************
128 *Des: 插入结点到表头(与在表尾操作类似)
129 *Ret: 成功返回0,失败返回-1
130 *********************************************/
131 int Insert_to_Head(LIST_INFO *plist, int num)
132 {
133 Test(plist);//函数入口检测
134
135 NODE *new_node = __Create_Node__(num);
136 if(NULL == new_node)
137 return -1;
138
139 if(IS_Empty_Link(plist))
140 {
141 plist->head = plist->tail = new_node;
142 }
143 else
144 {
145 new_node->next = plist->head;
146 plist->head = new_node;
147 }
148
149 plist->max++;
150
151 return 0;
152 }
153
154
155 /*******************************************
156 *Des: 删除数据域为num的结点
157 *Ret: 成功返回0,失败返回-1
158 *********************************************/
159 int Delete_Node_Num(LIST_INFO *plist, int num)
160 {
161 Test(plist);//函数入口检测
162
163 if(IS_Empty_Link(plist))
164 {
165 printf("The list is empty!\n");
166 return -1;
167 }
168
169 NODE *fnode, *tmpnode = NULL, *pnode = plist->head;
//第一次写的时候漏掉此处判断,
//当只有一个节点即是头结点又是尾结点时
if(plist->head->num == num && plist->max == 0)
{
fnode = plist->head;
plist->head = plist->tail = NULL;
free(fnode);
plist->max= 0;
return 0;
}
170 while(NULL != pnode)//查找该节点
171 {
172 if(pnode->num == num)
173 break;
174 tmpnode = pnode;
175 pnode = pnode->next;
176 }
177 if(pnode == NULL)//没有找到
178 {
179 printf("Have no such Node!\n");
180 return -1;
181 }
182 else if(NULL == tmpnode)//是头结点
183 {
184 fnode = plist->head;
185 plist->head = fnode->next;
186 }
187 else if(pnode == plist->tail)//是尾结点
188 {
189 fnode = plist->tail;
190 plist->tail = tmpnode;
191 plist->tail->next = NULL;
192 }
193 else
194 {
195 fnode = pnode;
196 tmpnode->next = fnode->next;
197 }
198 free(fnode);
199
200 return 0;
201
202 }
203
204 /*******************************************
205 *Des: 销毁链表
206 *Ret: 成功返回0,失败返回-1
207 *********************************************/
208 int Destory_Link(LIST_INFO **plist)// plist1 = &plist
209 { //*plist1 <==> plist;
210 Test(plist);//函数入口检测
211
212 Empty_Link(*plist);//清空链表
213
214 free(*plist);
215
216 *plist = NULL;
217
218 return 0;
219 }
220
221
222 /*******************************************
223 *Des: 遍历链表
224 *Ret: 成功返回0,失败返回-1
225 *********************************************/
226 int Traverse_Link(LIST_INFO *plist)
227 {
228 Test(plist);//函数入口检测
229
230 NODE *pnode = plist->head;
231
232 if(IS_Empty_Link(plist))
233 {
234 printf("The list is empty!\n");
235 return -1;
236 }
237
238 printf("The count of node: %d\n", plist->max);
239 while(NULL != pnode)
240 {
241 printf("%-5d", pnode->num);
242
243 pnode = pnode->next;
244 }
245 printf("\n\n");
246 return 0;
247 }
248
249
250 /*******************************************
251 *Des: 顺序表插入(从小到大)
252 *Ret: 成功返回0,失败返回-1
253 *********************************************/
254 int Insert_Order(LIST_INFO *plist, int num)
255 {
256 Test(plist); //函数入口检测
257
258 NODE *tmpnode = NULL, *pnode =NULL;
259
260 //创建新结点
261 NODE *new_node = __Create_Node__(num);
262 if(NULL == new_node)
263 {
264 return -1;
265 }
266
267 //链表为空
268 if(IS_Empty_Link(plist))
269 plist->head = plist->tail = new_node;
270
271 //如果第一个结点比待插入的结点数据域大
272 else if(plist->head->num >= new_node->num)
273 {
274 new_node->next = plist->head;
275 plist->head = new_node;
276 }
277 else
278 {
279 tmpnode = plist->head;
280 pnode = plist->head->next;
281 while(NULL != pnode)
282 {
283 if(pnode->num >= new_node->num)
284 break;
285 tmpnode = pnode;
286 pnode = pnode->next;
287 }
288 new_node->next = tmpnode->next;
289 tmpnode->next = new_node;
290 if(pnode == NULL)
291 plist->tail = new_node;
292 }
293 plist->max++;
294
295 return 0;
296 }