双向循环链表小结

以下是实现了一个简单的双向循环链表的一些功能:

其中宏函数:

            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 }

                                                                                                                                                                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值