zoukankan      html  css  js  c++  java
  • 链表

      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
    ",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******
    ","插入首部--打印");
    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******
    ","插入尾部--打印");
    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******
    ","插入中间--后边--打印");
    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******
    ","插入中间--前边--打印");
    409     printList(keys);
    410     
    411     //删除节点
    412     listDelNode(keys, node);
    413     printf("*****%s******
    ","删除第三个节点--打印");
    414     printList(keys);
    415     
    416     //复制节点
    417     copy = listDup(keys);
    418     printf("*****%s******
    ","复制节点--打印");
    419     printList(copy);
    420     
    421     //查找节点listSearchKey
    422     node = listSearchKey(keys, buf6);
    423     printf("*****%s******
    ","查找节点--listSearchKey--打印");
    424     printf("*****%s******
    ",node->value);
    425     
    426     
    427     //查找节点listIndex
    428     node = listIndex(keys, 3);
    429     printf("*****%s******
    ","查找节点--listIndex--打印");
    430     printf("*****%s******
    ",node->value);
    431     
    432     //查节点首节点放到尾节点
    433     listRotate(keys);
    434     printf("*****%s******
    ","节点首节点放到尾节点--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 */
  • 相关阅读:
    核心容器的两个接口(ApplicationContext和BeanFactory)引发出的问题
    ApplicationContext的三个常用实现类:
    IDEA如何找到接口的实现类
    编写BeanFactory
    9.4 Binder系统_驱动情景分析_服务使用过程
    9.3 Binder系统_驱动情景分析_服务获取过程
    9.2 Binder系统_驱动情景分析_服务注册过程
    9.1 Binder系统_C程序示例_框架分析和编写程序
    8.6 Android灯光系统_源码分析_背光灯
    8.5 Android灯光系统_源码分析_通知灯
  • 原文地址:https://www.cnblogs.com/huanhuanang/p/4519066.html
Copyright © 2011-2022 走看看