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 */