// 完成了单链表的所有操作: 增,删,前插,后插,回调遍历,复制,销毁,反转,排序 // 对于队列和栈就简单了,稍稍修改即可 #include <stdio.h> #include <stdlib.h> #include <assert.h> #define list_create(A) list_init(A) typedef struct node{ struct node *next; void *data; }node; typedef struct { node *head; }list_t; // 单链表 typedef struct { node *head; node *tail; }queue_t; // 队列 typedef struct { node *top; }stack_t; // 栈 inline static node *makenode(void *data); inline static void freenode(node *p); void list_init(list_t *list); size_t list_length(list_t *list); void list_destroy(list_t *list); node *list_getnode(list_t *list, int id); void list_add(list_t *list, void *data); void list_insertBack(list_t *list, node *n, void *data); void list_insertFront(list_t *list, node *n, void *data); void list_del(list_t *list, node *del); void list_traverse(list_t *list, void(*visit)(void *)); void list_reverse(list_t *list); void list_sort(list_t *list, int(*cmpar)(const void *, const void *)); void list_copy(list_t *dest, list_t *src); void list_add2(list_t *list, void *data); void list_del2(list_t *list, node *del); void list_insertFront2(list_t *list, node *n, void *data); void disp(int n); int cmpar(const void *data1, const void *data2); int main(int argc, char **argv); inline static node *makenode(void *data) { node *p; if( (p = malloc(sizeof(*p))) == NULL){ perror("malloc"); exit(1); } p->next = NULL; p->data = data; return p; } inline static void freenode(node *p) { free(p); } // 初始化 void list_init(list_t *list) { list->head = NULL; } size_t list_length(list_t *list) { node *p; int len; for(p = list->head, len = 0; p; p = p->next, len++) ; return len; } // 销毁一个链表 void list_destroy(list_t *list) { node *p; for(p = list->head; p; p = p->next) list_del(list, p); } // 按顺序编号获取某个节点 node *list_getnode(list_t *list, int id) { node *p; int n; for(p = list->head, n = 0; p; p = p->next, n++) if(n == id) return p; return NULL; // 最后1个节点的后继或没有找到 } // 添加 void list_add(list_t *list, void *data) { if(list->head == NULL){ // 特殊情况:头结点判断 list->head = makenode(data); }else{ node *p = list->head; while(p->next) // 获取最后一个节点 p = p->next; p->next = makenode(data); } } // 后插 void list_insertBack(list_t *list, node *n, void *data) { // assert(n); if(n == NULL) return; node *ins = makenode(data); ins->next = n->next; n->next = ins; } // 前插 void list_insertFront(list_t *list, node *n, void *data) { node *ins = makenode(data); ins->next = n; if(n == list->head){ // 特殊情况:头结点判断 list->head = ins; }else{ // 获取n的前驱 node *p; for(p = list->head; p; p = p->next) if(p->next == n){ p->next = ins; return; } } } // 删除一个节点 void list_del(list_t *list, node *del) { if(del == NULL) return; node *p; if(list->head == del){// 特殊情况:头结点判断 list->head = list->head->next; }else{ for(p = list->head; p; p = p->next) if(p->next == del){ p->next = del->next; freenode(del); } } } // 遍历 void list_traverse(list_t *list, void(*visit)(void *)) { node *p; if(list->head == NULL){ puts("empty !"); return; } for(p = list->head; p; p = p->next) visit(p->data); puts(""); } // 反转 void list_reverse(list_t *list) { node *tmp, *p, *head = NULL; for(p = list->head; p; p = tmp){ tmp = p->next; // 暂存p的后继节点 p->next = head, head = p; // 将p插到head前 } list->head = head; } // 排序 void list_sort(list_t *list, int(*cmpar)(const void *, const void *)) { size_t len; void **parr; node *p; int i; len = list_length(list); parr = malloc(sizeof(void *)*len); for(p = list->head, i = 0; p; p = p->next, i++) parr[i] = p->data; qsort(parr, len, sizeof(void *), cmpar); for(p = list->head, i = 0; p; p = p->next, i++) p->data = parr[i]; free(parr); } // 复制一个链表 void list_copy(list_t *dest, list_t *src) { node *p; for(p = src->head; p; p = p->next) list_add(dest, p->data); } // ----------------------------------------------------- void list_add2(list_t *list, void *data) { node **p; for(p = &list->head; *p; p = &(*p)->next) ; // 获取最后一个节点地址 *p = makenode(data); } void list_del2(list_t *list, node *del) { node **p; for(p = &(list->head); *p; p = &(*p)->next){ if(*p == del){ *p = del->next; freenode(del); if(*p == NULL) return; } } } void list_insertFront2(list_t *list, node *n, void *data) { node **p; node *ins = makenode(data); ins->next = n; for(p = &list->head; *p; p = &(*p)->next) if(*p == n){ *p = ins; return; } *p = ins; // n == NULL } // ------------------------------------------------- void disp(int n) { printf("%c_",n); } int cmpar(const void *data1, const void *data2) { return *(int *)data1 - *(int *)data2; } void(*show)(void *) = (void(*)(void *))disp; int main(int argc, char **argv) { list_t list; list_init(&list); list_insertFront(&list, list.head, (void *)'2'); list_insertFront(&list, list.head, (void *)'5'); list_insertFront(&list, list.head, (void *)'c'); list_insertFront(&list, list.head, (void *)'d'); list_traverse(&list, show); list_traverse(&list, show); node *p = list_getnode(&list, 2); // p==NULL list_insertBack(&list, p, (void *)'X'); list_traverse(&list, show); list_insertFront2(&list, p, (void *)'x'); list_traverse(&list, show); p = list_getnode(&list, 2); list_del(&list, p); list_traverse(&list, show); list_add2(&list, (void *)'3'); list_add2(&list, (void *)'1'); list_traverse(&list, show); list_reverse(&list); list_traverse(&list, show); list_t list2; list_init(&list2); list_copy(&list2, &list); list_traverse(&list2, show); list_destroy(&list2); list_traverse(&list2, show); // empty list_sort(&list, cmpar); list_traverse(&list, show); return 0; }