1 #include <stdio.h>
  2 #include <string.h>
  3 #include "zmalloc.h"
  4 
  5 #define AL_START_HEAD 0
  6 #define AL_START_TAIL 1
  7 #define listLength(l) ((l)->len)
  8 
  9 //定义节点
 10 typedef struct listNode {
 11     struct listNode *prev;
 12     struct listNode *next;
 13     void *value;
 14 } listNode;
 15 
 16 //定义链表
 17 typedef struct list {
 18     listNode *head;
 19     listNode *tail;
 20     void *(*dup)(void *ptr);
 21     void (*free)(void *ptr);
 22     int (*match)(void *ptr, void *key);
 23     unsigned long len;
 24 } list;
 25 
 26 //迭代器
 27 typedef struct listIter {
 28     listNode *next;
 29     int direction;
 30 } listIter;
 31 
 32 //创建一个空链表
 33 list *listCreate(void)
 34 {
 35     struct list *list;
 36 
 37     if ((list = zmalloc(sizeof(*list))) == NULL)
 38         return NULL;
 39     list->head = list->tail = NULL;
 40     list->len = 0;
 41     list->dup = NULL;
 42     list->free = NULL;
 43     list->match = NULL;
 44     return list;
 45 }
 46 
 47 /* Add a new node to the list, to head, containing the specified 'value'
 48  * pointer as value.
 49  *
 50  * On error, NULL is returned and no operation is performed (i.e. the
 51  * list remains unaltered).
 52  * On success the 'list' pointer you pass to the function is returned. */
 53 list *listAddNodeHead(list *list, void *value)
 54 {
 55     listNode *node;
 56 
 57     if ((node = zmalloc(sizeof(*node))) == NULL)
 58         return NULL;
 59     node->value = value;
 60     if (list->len == 0) {
 61         list->head = list->tail = node;
 62         node->prev = node->next = NULL;
 63     } else {
 64         node->prev = NULL;
 65         node->next = list->head;
 66         list->head->prev = node;
 67         list->head = node;
 68     }
 69     list->len++;
 70     return list;
 71 }
 72 
 73 /* Add a new node to the list, to tail, containing the specified 'value'
 74  * pointer as value.
 75  *
 76  * On error, NULL is returned and no operation is performed (i.e. the
 77  * list remains unaltered).
 78  * On success the 'list' pointer you pass to the function is returned. */
 79 list *listAddNodeTail(list *list, void *value)
 80 {
 81     listNode *node;
 82 
 83     if ((node = zmalloc(sizeof(*node))) == NULL)
 84         return NULL;
 85     node->value = value;
 86     if (list->len == 0) {
 87         list->head = list->tail = node;
 88         node->prev = node->next = NULL;
 89     } else {
 90         node->prev = list->tail;
 91         node->next = NULL;
 92         list->tail->next = node;
 93         list->tail = node;
 94     }
 95     list->len++;
 96     return list;
 97 }
 98 
 99 /* Free the whole list.
100  *
101  * This function can't fail. */
102 void listRelease(list *list)
103 {
104     unsigned long len;
105     listNode *current, *next;
106 
107     current = list->head;
108     len = list->len;
109     while(len--) {
110         next = current->next;
111         if (list->free) list->free(current->value);
112         zfree(current);
113         current = next;
114     }
115     zfree(list);
116 }
117 
118 /*
119 listInsertNode:插入节点
120 */
121 list *listInsertNode(list *list, listNode *old_node, void *value, int after) 
122 {
123     listNode *node;
124 
125     if ((node = zmalloc(sizeof(*node))) == NULL)
126         return NULL;
127     node->value = value;
128     if (after) {
129         node->prev = old_node;
130         node->next = old_node->next;
131         if (list->tail == old_node) {
132             list->tail = node;
133         }
134     } else {
135         node->next = old_node;
136         node->prev = old_node->prev;
137         if (list->head == old_node) {
138             list->head = node;
139         }
140     }
141     if (node->prev != NULL) {
142         node->prev->next = node;
143     }
144     if (node->next != NULL) {
145         node->next->prev = node;
146     }
147     list->len++;
148     return list;
149 }
150 
151 /* Remove the specified node from the specified list.
152  * It's up to the caller to free the private value of the node.
153  *
154  * This function can't fail. */
155 void listDelNode(list *list, listNode *node)
156 {
157     if (node->prev)
158         node->prev->next = node->next;
159     else
160         list->head = node->next;
161     if (node->next)
162         node->next->prev = node->prev;
163     else
164         list->tail = node->prev;
165     if (list->free) list->free(node->value);
166     zfree(node);
167     list->len--;
168 }
169 
170 /* Returns a list iterator 'iter'. After the initialization every
171  * call to listNext() will return the next element of the list.
172  *
173  * This function can't fail. */
174 listIter *listGetIterator(list *list, int direction)
175 {
176     listIter *iter;
177 
178     if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
179     if (direction == AL_START_HEAD)
180         iter->next = list->head;
181     else
182         iter->next = list->tail;
183     iter->direction = direction;
184     return iter;
185 }
186 
187 /* Release the iterator memory */
188 void listReleaseIterator(listIter *iter) {
189     zfree(iter);
190 }
191 
192 /* Create an iterator in the list private iterator structure */
193 void listRewind(list *list, listIter *li) {
194     li->next = list->head;
195     li->direction = AL_START_HEAD;
196 }
197 
198 void listRewindTail(list *list, listIter *li) {
199     li->next = list->tail;
200     li->direction = AL_START_TAIL;
201 }
202 
203 
204 /* Return the next element of an iterator.
205  * It's valid to remove the currently returned element using
206  * listDelNode(), but not to remove other elements.
207  *
208  * The function returns a pointer to the next element of the list,
209  * or NULL if there are no more elements, so the classical usage patter
210  * is:
211  *
212  * iter = listGetIterator(list,<direction>);
213  * while ((node = listNext(iter)) != NULL) {
214  *     doSomethingWith(listNodeValue(node));
215  * }
216  *
217  * */
218 listNode *listNext(listIter *iter)
219 {
220     listNode *current = iter->next;
221 
222     if (current != NULL) {
223         if (iter->direction == AL_START_HEAD)
224             iter->next = current->next;
225         else
226             iter->next = current->prev;
227     }
228     return current;
229 }
230 
231 /* Duplicate the whole list. On out of memory NULL is returned.
232  * On success a copy of the original list is returned.
233  *
234  * The 'Dup' method set with listSetDupMethod() function is used
235  * to copy the node value. Otherwise the same pointer value of
236  * the original node is used as value of the copied node.
237  *
238  * The original list both on success or error is never modified. */
239 list *listDup(list *orig)
240 {
241     list *copy;
242     listIter *iter;
243     listNode *node;
244 
245     if ((copy = listCreate()) == NULL)
246         return NULL;
247     copy->dup = orig->dup;
248     copy->free = orig->free;
249     copy->match = orig->match;
250     iter = listGetIterator(orig, AL_START_HEAD);
251     while((node = listNext(iter)) != NULL) {
252         void *value;
253 
254         if (copy->dup) {
255             value = copy->dup(node->value);
256             if (value == NULL) {
257                 listRelease(copy);
258                 listReleaseIterator(iter);
259                 return NULL;
260             }
261         } else
262             value = node->value;
263         if (listAddNodeTail(copy, value) == NULL) {
264             listRelease(copy);
265             listReleaseIterator(iter);
266             return NULL;
267         }
268     }
269     listReleaseIterator(iter);
270     return copy;
271 }
272 
273 /* Search the list for a node matching a given key.
274  * The match is performed using the 'match' method
275  * set with listSetMatchMethod(). If no 'match' method
276  * is set, the 'value' pointer of every node is directly
277  * compared with the 'key' pointer.
278  *
279  * On success the first matching node pointer is returned
280  * (search starts from head). If no matching node exists
281  * NULL is returned. */
282 listNode *listSearchKey(list *list, void *key)
283 {
284     listIter *iter;
285     listNode *node;
286 
287     iter = listGetIterator(list, AL_START_HEAD);
288     while((node = listNext(iter)) != NULL) {
289         if (list->match) {
290             if (list->match(node->value, key)) {
291                 listReleaseIterator(iter);
292                 return node;
293             }
294         } else {
295             if (key == node->value) {
296                 listReleaseIterator(iter);
297                 return node;
298             }
299         }
300     }
301     listReleaseIterator(iter);
302     return NULL;
303 }
304 
305 /* Return the element at the specified zero-based index
306  * where 0 is the head, 1 is the element next to head
307  * and so on. Negative integers are used in order to count
308  * from the tail, -1 is the last element, -2 the penultimate
309  * and so on. If the index is out of range NULL is returned. */
310 listNode *listIndex(list *list, long index) {
311     listNode *n;
312 
313     if (index < 0) {
314         index = (-index)-1;
315         n = list->tail;
316         while(index-- && n) n = n->prev;
317     } else {
318         n = list->head;
319         while(index-- && n) n = n->next;
320     }
321     return n;
322 }
323 
324 /* Rotate the list removing the tail node and inserting it to the head. */
325 void listRotate(list *list) {
326     listNode *tail = list->tail;
327 
328     if (listLength(list) <= 1) return;
329 
330     /* Detach current tail */
331     list->tail = tail->prev;
332     list->tail->next = NULL;
333     /* Move it as head */
334     list->head->prev = tail;
335     tail->prev = NULL;
336     tail->next = list->head;
337     list->head = tail;
338 }
339 
340 
341 //打印List
342 void printList(list *keys)
343 {
344     int len;
345     int i;
346     listNode *current;
347     
348     len = keys->len;
349     i = len;
350     current = keys->head;
351     while(len--) {
352         printf("keys[%d] is %s\n",i-len-1,current->value);
353         current = current->next;
354     }
355 }
356 
357 
358 int main()
359 {
360     list *keys = listCreate();
361     list *copy;
362     unsigned long len;
363     unsigned long i;
364     
365     listNode *node;
366     
367     
368     //插入首部
369     char buf[1024];
370     strcpy(buf,"i am zhaoja");
371     char buf2[1024];
372     strcpy(buf2,"i am xm");
373     
374     listAddNodeHead(keys,buf);
375     listAddNodeHead(keys,buf2);
376 
377     printf("*****%s******\n","插入首部--打印");
378     printList(keys);
379     
380     
381     //插入尾部
382     char buf3[1024];
383     strcpy(buf3,"i am x3");
384     char buf4[1024];
385     strcpy(buf4,"i am x4");
386     
387     listAddNodeTail(keys,buf3);
388     listAddNodeTail(keys,buf4);
389     
390     printf("*****%s******\n","插入尾部--打印");
391     printList(keys);
392     
393     //插入中间后边
394     char buf5[1024];
395     strcpy(buf5,"i am x5");
396     node=keys->head->next;
397     listInsertNode(keys, node, buf5, 1) ;
398     
399     printf("*****%s******\n","插入中间--后边--打印");
400     printList(keys);
401     
402     //插入中间前边
403     char buf6[1024];
404     strcpy(buf6,"i am x6");
405     node=keys->head->next;
406     listInsertNode(keys, node, buf6, 0) ;
407     
408     printf("*****%s******\n","插入中间--前边--打印");
409     printList(keys);
410     
411     //删除节点
412     listDelNode(keys, node);
413     printf("*****%s******\n","删除第三个节点--打印");
414     printList(keys);
415     
416     //复制节点
417     copy = listDup(keys);
418     printf("*****%s******\n","复制节点--打印");
419     printList(copy);
420     
421     //查找节点listSearchKey
422     node = listSearchKey(keys, buf6);
423     printf("*****%s******\n","查找节点--listSearchKey--打印");
424     printf("*****%s******\n",node->value);
425     
426     
427     //查找节点listIndex
428     node = listIndex(keys, 3);
429     printf("*****%s******\n","查找节点--listIndex--打印");
430     printf("*****%s******\n",node->value);
431     
432     //查节点首节点放到尾节点
433     listRotate(keys);
434     printf("*****%s******\n","节点首节点放到尾节点--listRotate--打印");
435     printList(keys);
436     
437     
438     
439     listRelease(keys);
440     listRelease(copy);
441     return 0;
442 }
443 
444 /*
445 测试代码
446 [root@rac1 List]# gcc listcreate.c zmalloc.c
447 [root@rac1 List]# ./a.out 
448 *****插入首部--打印******
449 keys[0] is i am xm
450 keys[1] is i am zhaoja
451 *****插入尾部--打印******
452 keys[0] is i am xm
453 keys[1] is i am zhaoja
454 keys[2] is i am x3
455 keys[3] is i am x4
456 *****插入中间--后边--打印******
457 keys[0] is i am xm
458 keys[1] is i am zhaoja
459 keys[2] is i am x5
460 keys[3] is i am x3
461 keys[4] is i am x4
462 *****插入中间--前边--打印******
463 keys[0] is i am xm
464 keys[1] is i am x6
465 keys[2] is i am zhaoja
466 keys[3] is i am x5
467 keys[4] is i am x3
468 keys[5] is i am x4
469 *****删除第三个节点--打印******
470 keys[0] is i am xm
471 keys[1] is i am x6
472 keys[2] is i am x5
473 keys[3] is i am x3
474 keys[4] is i am x4
475 *****复制节点--打印******
476 keys[0] is i am xm
477 keys[1] is i am x6
478 keys[2] is i am x5
479 keys[3] is i am x3
480 keys[4] is i am x4
481 *****查找节点--listSearchKey--打印******
482 *****i am x6******
483 *****查找节点--listIndex--打印******
484 *****i am x3******
485 *****节点首节点放到尾节点--listRotate--打印******
486 keys[0] is i am x4
487 keys[1] is i am xm
488 keys[2] is i am x6
489 keys[3] is i am x5
490 keys[4] is i am x3
491 
492 */

 

posted on 2015-05-21 10:31  充实自己  阅读(241)  评论(0编辑  收藏  举报