以下是实现了一个简单的双向循环链表的一些功能:
其中宏函数:
list_for_each_next(struct node *pos, struct node *head)
list_for_each_prev(struct node *pos, struct node *head)
文件内部函数:
static void init_list_head(struct node *head)
static int reset_node_index(struct node * head)
static void * search_index_node(struct node *head, int index)
static void _list_add(struct node *new, struct node *prev, struct node * next)
static void _list_add_list(struct node *list, struct node *prev, struct node *next)
static void _list_del_node(struct node *prev, struct node *next)
static void _list_node_replace(struct node *old, struct node *new)
static void * list_has_node(struct node *head, int data)
文件对外函数:
void list_add_tail(struct node *new, struct node *head)
void list_add_node(struct node *new, struct node *head, int index)
void list_add_list(struct node *list, struct node *head, int index)
void list_del_node(struct node *head, int index)
void list_node_replace(struct node *head, struct node *new, int index)
void list_node_move(struct node *head, int data, int index)
void InitList(struct node * head, int data[], int len)
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define LEN 8
5 //链表的正向遍历宏函数
6 #define list_for_each_next(pos, head) \
7 for(pos = (head)->next; pos != (head); pos = pos->next)
8
9 //链表的反向遍历宏函数
10 #define list_for_each_prev(pos, head) \
11 for(pos = (head)->prev; pos != (head); pos = pos->prev)
12
13 int d;
14 struct node{
15 struct node * next;
16 struct node * prev;
17 int data;
18 int index;
19 };
20
21 /*检查一个链表是否为空
22 head为该链表的头节点
23 是空链表返回1,否则返回0
24 * */
25 int list_is_empty(struct node *head)
26 {
27 return head->next == head;
28 }
29
30 /*
31 在链表中查询某个节点是否存在
32 head为链表的头节点
33 search为要查找的节点
34 如果存在要查找的节点返回1,否则返回0
35 */
36 static void * list_has_node(struct node *head, int data)
37 {
38 struct node *pos;
39
40 list_for_each_next(pos, head)
41 {
42 if(data == pos->data)
43 {
44 return pos;
45 }
46 }
47 return NULL;
48 }
49
50
51 /*检查一个节点是否为尾节点
52 * list为要检查的节点,head链表中的头节点
53 * 是最后一个节点返回1,否则返回0
54 * */
55 int list_is_last_node(struct node *list, struct node *head)
56 {
57 return list->next == head;
58 }
59
60 /*测试只有2个节点
61 head为链表的头节点
62 如果只有2个节点返回1,否则返回0
63 */
64 int list_has_tow_node(struct node *head)
65 {
66 return (!list_is_empty(head)) && (head->next == head->prev);
67 }
68
69
70 /*初始化链表的头节点*/
71 static void init_list_head(struct node *head)
72 {
73 head->next = head;
74 head->prev = head;
75 }
76
77 /*
78 链表的节点下标索引重置
79 head为链表的头节点
80 设置头结点之后的节点下标从1开始
81 返回除头节点以外其余节点的个数
82 */
83 static int reset_node_index(struct node * head)
84 {
85 struct node *pos;
86 int index = 0;
87 list_for_each_next(pos, head)
88 {
89 index++;
90 pos->index = index;
91 }
92 return index;
93 }
94
95
96 /*
97 从链表中查找一个节点
98 head为链表的头节点
99 index为节点的索引
100 */
101 static void * search_index_node(struct node *head, int index)
102 {
103 int j;
104 int length;
105 struct node *p;
106
107 if(list_is_empty(head))
108 return NULL;
109
110 length = reset_node_index(head);
111 if(index <= length/2)
112 {
113 j = 1;
114 p = head->next;
115 while(j < index)
116 {
117 p = p->next;
118 j++;
119 }
120 }
121 else
122 {
123 j = length;
124 p = head->prev;
125 while(j > index)
126 {
127 p = p->prev;
128 j--;
129 }
130 }
131 return p;
132 }
133
134 /*
135 new为要插入的新节点
136 prev为该链表的尾节
137 next为该链表的头节点
138 */
139 static void _list_add(struct node *new, struct node *prev, struct node * next)
140 {
141 next->prev = new;
142 new->next = next;
143 new->prev = prev;
144 prev->next = new;
145 }
146 /*
147 从链表尾部添加节点
148 new为要插入的新节点
149 head为该链表的头节点
150 */
151 void list_add_tail(struct node *new, struct node *head)
152 {
153 _list_add(new, head->prev, head);
154 }
155
156 /*
157 在链表的某个位置添加一个节点
158 new为要添加的节点
159 head为该链表的头节点
160 index为要添加节点的位置
161 */
162 void list_add_node(struct node *new, struct node *head, int index)
163 {
164 struct node *p;
165
166 p = (struct node *)search_index_node(head, index);
167 _list_add(new, p->prev, p);
168 reset_node_index(head);
169 }
170
171 /*
172 list为新添加的链表
173 prev为被插入链表位置的前一个节点
174 next为被插入链表位置的当前节点
175 */
176 static void _list_add_list(struct node *list, struct node *prev, struct node *next)
177 {
178 struct node *first = list->next;
179 struct node *last = list->prev;
180
181 first->prev = prev;
182 last->next = next;
183 next->prev = last;
184 prev->next = first;
185 }
186 /*
187 在一条链表中插入新的链表的节点
188 list为新添加的链表
189 head为被插入的链表
190 index为要把list插入head链表中的位置
191 */
192 void list_add_list(struct node *list, struct node *head, int index)
193 {
194 struct node *p;
195 if(!list_is_empty(list))
196 {
197 p = (struct node *)search_index_node(head, index);
198 _list_add_list(list, p->prev, p);
199 }
200 reset_node_index(head);
201 }
202
203
204 /*
205 prev为删除节点的上一个节点
206 next为删除节点的下一个节点
207 */
208 static void _list_del_node(struct node *prev, struct node *next)
209 {
210 prev->next = next;
211 next->prev = prev;
212 }
213 /*
214 从链表中删除节点
215 entry为该链表中要删除的节点
216 */
217 void list_del_node(struct node *head, int index)
218 {
219 struct node *entry;
220 entry = (struct node *)search_index_node(head, index);
221 _list_del_node(entry->prev, entry->next);
222 init_list_head(entry);
223 reset_node_index(head);
224 }
225
226 /*
227 old为链表中被替换的节点
228 new为链表中替换old的新节点
229 * */
230 static void _list_node_replace(struct node *old, struct node *new)
231 {
232 new->next = old->next;
233 new->prev = old->prev;
234 new->next->prev = new;
235 new->prev->next = new;
236 }
237 /*
238 替换链表中某个节点
239 head为链表中头节点
240 new为替换的新节点
241 index为链表中节点的下标数
242 */
243 void list_node_replace(struct node *head, struct node *new, int index)
244 {
245 struct node *old;//被替换的节点
246
247 old = (struct node *)search_index_node(head, index);
248 new->index = old->index;
249
250 _list_node_replace(old, new);
251 init_list_head(old);
252 }
253
254 /*
255 查询列表中存在不存在某个数据,如果存在将其所在节点移动到列表中相应的位置
256 head要查询的列表的头节点
257 data要查询的某项数据
258 index列表中节点的所在位置
259 */
260 void list_node_move(struct node *head, int data, int index)
261 {
262 struct node *search;
263
264 if(list_is_empty(head))
265 return;
266 search =(struct node *)list_has_node(head, data);
267 if(search != NULL && search->index != index)
268 {
269 _list_del_node(search->prev, search->next);
270 list_add_node(search, head, index);
271 }
272 }
273
274 /*
275 链表初始化
276 head为链表的头指针
277 data为需要在链表节点中添加的数据
278 len为data的长度
279 */
280 void InitList(struct node * head, int data[], int len)
281 {
282 struct node *new;
283 init_list_head(head);
284 int i;
285 for(i = 0; i < len; i++)
286 {
287 new = (struct node *)malloc(sizeof(struct node));
288 new->data = data[i];
289 new->index = i+1;
290 list_add_tail(new, head);
291 }
292 }
293
294
295 /*打印链表*/
296 void print(struct node * head)
297 {
298 struct node *p;
299 printf("以下是链表正向输出:\n");
300 for(p = head->next; p != head; p = p->next)
301 printf("%d[%d] ", p->data, p->index);
302 printf("\n");
303
304 }
305
306
307 void main()
308 {
309 struct node *head;
310 struct node *new;
311 struct node *p;
312 struct node *list;
313 int * data;
314 int len = LEN;
315 int d[3];
316 head = (struct node *)malloc(sizeof(struct node));
317 new = (struct node *)malloc(sizeof(struct node));
318 p = (struct node *)malloc(sizeof(struct node));
319 list = (struct node *)malloc(sizeof(struct node));
320
321 p->data = 44;
322 new->data = 20;
323
324 init_list_head(list);
325 int i;
326 struct node *q;
327 for(i = 0; i < 3; i++)
328 {
329 q = (struct node *)malloc(sizeof(struct node));
330 d[i] = i+1;
331 q->data = d[i];
332 list_add_tail(q, list);
333 }
334 data = (int *)malloc(len*sizeof(int));
335 for(i = 0; i < len; i++)
336 {
337 data[i] = i+2;
338 }
339
340 printf("输入下列值验证功能:\n");
341 printf("1.初始化含有8个节点的链表,节点数从2开始递增\n");
342 printf("2.在该链表第2个节点处插入一个新的节点数据为20\n");
343 printf("3.在该链表中删除第5个位置上的节点\n");
344 printf("4.在该链表中将第1个节点替换为新的节点数据为44\n");
345 printf("5.在该链表中第6个节点的位置插入一个新的含有三个节点的链表\n");
346 printf("6.在该链表中是否存在数据9,如果存在将其所在节点移动到链表中1的位置\n");
347 scanf("%d", &i);
348 while(i > 0)
349 {
350 scanf("%d", &i);
351 switch(i)
352 {
353 case 1:
354 InitList(head, data, len);
355 free(data);
356 print(head);
357 break;
358 case 2:
359 list_add_node(new,head,2);
360 // free(new);
361 print(head);
362 break;
363 case 3:
364 list_del_node(head, 5);
365 print(head);
366 break;
367 case 4:
368 list_node_replace(head, p, 1);
369 // free(p);
370 print(head);
371 break;
372 case 5:
373 list_add_list(list, head, 6);
374 // free(list);
375 print(head);
376 break;
377 case 6:
378 list_node_move(head, 9, 1);
379 print(head);
380 break;
381 }
382 }
383 }