============================== 2022-8-5 ==============================
note 一.早测
完成有头双向循环链表的功能
1.创建头结点
2.插入数据结点
3.遍历链表
4.销毁链表
5.查找结点
6.删除结点
7.拿出结点
只写声明和实现,不用写调用(llist.c 和 llist.h)
=================================
作业
1.把这一周讲过的内容都完完整整的复习一遍
2.把三个版本的通用性强的链表重新实现一遍
3.在纸上写链表的代码
=================================
通用性强的链表 结点图
main.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include <stdio.h> #include <string.h> #include "llist.h" #define NAMESIZE 20 struct stu //客户自己创建的数据结构体{ int id; char name[NAMESIZE]; int math; int age; int tel; }; void print (const void *data) { const struct stu *p = data; printf ("%d %s %d %d %d\n" ,p->id,p->name,p->math,p->age, p->tel); } int id_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->id - *k); } int name_cmp (const void *data, const void *key) { const struct stu *p = data; const char *k = key; return !(strcmp (p->name, k)); } int tel_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->tel - *k); } int main (void ) { LLIST *handler = NULL ; struct stu data ; struct stu save ; struct stu *find = NULL ; int i = 0 ; int ret = 0 ; int find_id = 100 ; int find_tel = 10002 ; char *find_name = "stu4" ; handler = llist_create(sizeof (struct stu)); if (handler == NULL ) return -1 ; for (i = 0 ; i < 5 ; i++) { data.id = 100 + i; sprintf (data.name, "stu%d" , i); data.math = 100 - i; data.age = 20 + i; data.tel = 10000 + i; llist_insert(handler,&data,TAILINSERT); } llist_display(handler, print); printf ("============================\n" ); #if 0 ret = llist_delete(handler, &find_tel, tel_cmp); if (ret != 0 ) printf ("Delete It Is Failed!\n" ); else printf ("Delete It!\n" ); #else ret = llist_fetch(handler, &find_tel, tel_cmp, &save); if (ret != 0 ) printf ("Fetch It Is Failed!\n" ); else { printf ("Fetch It!\n" ); print(&save); } #endif printf ("============================\n" ); llist_display(handler, print); llist_destroy(handler); return 0 ; }
llist.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #ifndef __LLIST_H #define __LLIST_H #define HEADINSERT 0 #define TAILINSERT 1 typedef void (*llist_op) (const void *) ;typedef int (*llist_cmp) (const void *,const void *) ;struct llist_node //数据结点的结构体{ void *data; struct llist_node *prev ; struct llist_node *next ; }; typedef struct llist_head //头结点的结构体{ int size; struct llist_node head ; }LLIST; LLIST *llist_create (int ) ; int llist_insert (LLIST *, const void *, int ) ;void llist_display (LLIST *, llist_op) ;void llist_destroy (LLIST *) ;void *llist_find (LLIST *, const void *, llist_cmp) ;int llist_delete (LLIST *, const void *, llist_cmp) ;int llist_fetch (LLIST *, const void *, llist_cmp, void *) ;#endif
llist.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "llist.h" LLIST *llist_create (int size) { LLIST *handler = NULL ; handler = malloc (sizeof (LLIST)); if (handler == NULL ) return NULL ; handler->size = size; handler->head.prev = &handler->head; handler->head.next = &handler->head; return handler; } int llist_insert (LLIST *handler,const void *data,int mode) { struct llist_node *p = &handler->head; struct llist_node *newnode = NULL ; newnode = malloc (sizeof (struct llist_node)); if (newnode == NULL ) return -1 ; newnode->data=malloc (handler->size); if (newnode->data == NULL ) { free (newnode); return -2 ; } memcpy (newnode->data, data, handler->size); switch (mode) { case HEADINSERT : break ; case TAILINSERT : p = p->prev; break ; default : free (newnode->data); free (newnode); return -3 ; } newnode->next = p->next; newnode->prev = p; newnode->next->prev = newnode; newnode->prev->next = newnode; return 0 ; } void llist_display (LLIST *handler, llist_op op) { struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) op(cur->data); } void llist_destroy (LLIST *handler) { struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=handler->head.next) { cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur->data); free (cur); } free (handler); } struct llist_node *_find (LLIST *handler , const void *find_data , llist_cmp cmp ){ struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) if (cmp(cur->data, find_data)) return cur; return NULL ; } void *llist_find (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return NULL ; return cur->data; } int llist_delete (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur->data); free (cur); return 0 ; } int llist_fetch (LLIST *handler, const void *find_data, llist_cmp cmp, void *save) { struct llist_node *cur = NULL ; cur = _find(handler,find_data,cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; memcpy (save, cur->data, handler->size); free (cur->data); free (cur); return 0 ; }
makefile 1 2 3 4 llist : main.o llist.o gcc -o $@ $^ clean : rm -rf *.o llist
可变长的通用性强的链表 =================================
可变长的结构体 需要把可变长的因子放到结构体定义的最后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <stdio.h> #include <stdlib.h> struct aaa { void *data; struct aaa *prev ; struct aaa *next ; }; struct bbb { struct bbb *prev ; struct bbb *next ; char data[0 ]; }; int main (int argc, char *argv[]) { struct bbb *newnode = NULL ; printf ("sizeof(struct aaa) = %ld\n" , sizeof (struct aaa)); printf ("sizeof(struct bbb) = %ld\n" , sizeof (struct bbb)); newnode = malloc (sizeof (struct bbb) + 40 ); return 0 ; }
=================================
main.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include <stdio.h> #include <string.h> #include "llist.h" #define NAMESIZE 20 struct stu //客户自己创建的数据结构体{ int id; char name[NAMESIZE]; int math; int age; int tel; }; void print (const void *data) { const struct stu *p = data; printf ("%d %s %d %d %d\n" ,p->id,p->name,p->math,p->age, p->tel); } int id_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->id - *k); } int name_cmp (const void *data, const void *key) { const struct stu *p = data; const char *k = key; return !(strcmp (p->name, k)); } int tel_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->tel - *k); } int main (void ) { LLIST *handler = NULL ; struct stu data ; struct stu save ; struct stu *find = NULL ; int i = 0 ; int ret = 0 ; int find_id = 100 ; int find_tel = 10002 ; char *find_name = "stu4" ; handler = llist_create(sizeof (struct stu)); if (handler == NULL ) return -1 ; for (i = 0 ; i < 5 ; i++) { data.id = 100 + i; sprintf (data.name, "stu%d" , i); data.math = 100 - i; data.age = 20 + i; data.tel = 10000 + i; llist_insert(handler,&data,TAILINSERT); } llist_display(handler, print); printf ("============================\n" ); #if 0 ret = llist_delete(handler, &find_tel, tel_cmp); if (ret != 0 ) printf ("Delete It Is Failed!\n" ); else printf ("Delete It!\n" ); #else ret = llist_fetch(handler, &find_tel, tel_cmp, &save); if (ret != 0 ) printf ("Fetch It Is Failed!\n" ); else { printf ("Fetch It!\n" ); print(&save); } #endif printf ("============================\n" ); llist_display(handler, print); llist_destroy(handler); return 0 ; }
llist.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #ifndef __LLIST_H #define __LLIST_H #define HEADINSERT 0 #define TAILINSERT 1 typedef void (*llist_op) (const void *) ;typedef int (*llist_cmp) (const void *,const void *) ;struct llist_node //数据结点的结构体(可变长的结构体){ struct llist_node *prev ; struct llist_node *next ; char data[0 ]; }; typedef struct llist_head //头结点的结构体{ int size; struct llist_node head ; }LLIST; LLIST *llist_create (int ) ; int llist_insert (LLIST *, const void *, int ) ;void llist_display (LLIST *, llist_op) ;void llist_destroy (LLIST *) ;void *llist_find (LLIST *, const void *, llist_cmp) ;int llist_delete (LLIST *, const void *, llist_cmp) ;int llist_fetch (LLIST *, const void *, llist_cmp, void *) ;#endif
llist.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "llist.h" LLIST *llist_create (int size) { LLIST *handler = NULL ; handler = malloc (sizeof (LLIST)); if (handler == NULL ) return NULL ; handler->size = size; handler->head.prev = &handler->head; handler->head.next = &handler->head; return handler; } int llist_insert (LLIST *handler,const void *data,int mode) { struct llist_node *p = &handler->head; struct llist_node *newnode = NULL ; newnode = malloc (sizeof (struct llist_node) + handler->size); if (newnode == NULL ) return -1 ; memcpy (newnode->data, data, handler->size); switch (mode) { case HEADINSERT : break ; case TAILINSERT : p = p->prev; break ; default : free (newnode); return -3 ; } newnode->next = p->next; newnode->prev = p; newnode->next->prev = newnode; newnode->prev->next = newnode; return 0 ; } void llist_display (LLIST *handler, llist_op op) { struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) op(cur->data); } void llist_destroy (LLIST *handler) { struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=handler->head.next) { cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur); } free (handler); } struct llist_node *_find (LLIST *handler , const void *find_data , llist_cmp cmp ){ struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) if (cmp(cur->data, find_data)) return cur; return NULL ; } void *llist_find (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return NULL ; return cur->data; } int llist_delete (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur); return 0 ; } int llist_fetch (LLIST *handler, const void *find_data, llist_cmp cmp, void *save) { struct llist_node *cur = NULL ; cur = _find(handler,find_data,cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; memcpy (save, cur->data, handler->size); free (cur); return 0 ; }
makefile 1 2 3 4 llist : main.o llist.o gcc -o $@ $^ clean : rm -rf *.o llist
=================================
封装通用性强的链表 main.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 #include <stdio.h> #include <string.h> #include "llist.h" #define NAMESIZE 20 struct stu //客户自己创建的数据结构体{ int id; char name[NAMESIZE]; int math; int age; int tel; }; void print (const void *data) { const struct stu *p = data; printf ("%d %s %d %d %d\n" ,p->id,p->name,p->math,p->age, p->tel); } int id_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->id - *k); } int name_cmp (const void *data, const void *key) { const struct stu *p = data; const char *k = key; return !(strcmp (p->name, k)); } int tel_cmp (const void *data, const void *key) { const struct stu *p = data; const int *k = key; return !(p->tel - *k); } int main (void ) { LLIST *handler = NULL ; struct stu data ; struct stu save ; struct stu *find = NULL ; int i = 0 ; int ret = 0 ; int find_id = 100 ; int find_tel = 10002 ; char *find_name = "stu4" ; handler = llist_create(sizeof (struct stu)); if (handler == NULL ) return -1 ; for (i = 0 ; i < 5 ; i++) { data.id = 100 + i; sprintf (data.name, "stu%d" , i); data.math = 100 - i; data.age = 20 + i; data.tel = 10000 + i; llist_insert(handler,&data,TAILINSERT); } llist_display(handler, print); printf ("============================\n" ); #if 0 ret = llist_delete(handler, &find_tel, tel_cmp); if (ret != 0 ) printf ("Delete It Is Failed!\n" ); else printf ("Delete It!\n" ); #else ret = llist_fetch(handler, &find_tel, tel_cmp, &save); if (ret != 0 ) printf ("Fetch It Is Failed!\n" ); else { printf ("Fetch It!\n" ); print(&save); } #endif printf ("============================\n" ); llist_display(handler, print); llist_destroy(handler); return 0 ; }
llist.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #ifndef __LLIST_H #define __LLIST_H #define HEADINSERT 0 #define TAILINSERT 1 typedef void (*llist_op) (const void *) ;typedef int (*llist_cmp) (const void *,const void *) ;typedef void LLIST;LLIST *llist_create (int ) ; int llist_insert (LLIST *, const void *, int ) ;void llist_display (LLIST *, llist_op) ;void llist_destroy (LLIST *) ;void *llist_find (LLIST *, const void *, llist_cmp) ;int llist_delete (LLIST *, const void *, llist_cmp) ;int llist_fetch (LLIST *, const void *, llist_cmp, void *) ;#endif
llist.c 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "llist.h" struct llist_node //数据结点的结构体(可变长的结构体){ struct llist_node *prev ; struct llist_node *next ; char data[0 ]; }; struct llist_head //头结点的结构体{ int size; struct llist_node head ; }; LLIST *llist_create (int size) { struct llist_head *handler = NULL ; handler = malloc (sizeof (LLIST)); if (handler == NULL ) return NULL ; handler->size = size; handler->head.prev = &handler->head; handler->head.next = &handler->head; return handler; } int llist_insert (LLIST *h,const void *data,int mode) { struct llist_head *handler = h; struct llist_node *p = &handler->head; struct llist_node *newnode = NULL ; newnode = malloc (sizeof (struct llist_node) + handler->size); if (newnode == NULL ) return -1 ; memcpy (newnode->data, data, handler->size); switch (mode) { case HEADINSERT : break ; case TAILINSERT : p = p->prev; break ; default : free (newnode); return -3 ; } newnode->next = p->next; newnode->prev = p; newnode->next->prev = newnode; newnode->prev->next = newnode; return 0 ; } void llist_display (LLIST *h, llist_op op) { struct llist_head *handler = h; struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) op(cur->data); } void llist_destroy (LLIST *h) { struct llist_head *handler = h; struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=handler->head.next) { cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur); } free (handler); } struct llist_node *_find (LLIST *h , const void *find_data , llist_cmp cmp ){ struct llist_head *handler = h; struct llist_node *cur = NULL ; for (cur=handler->head.next;cur!=&handler->head;cur=cur->next) if (cmp(cur->data, find_data)) return cur; return NULL ; } void *llist_find (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return NULL ; return cur->data; } int llist_delete (LLIST *handler, const void *find_data, llist_cmp cmp) { struct llist_node *cur = NULL ; cur = _find(handler, find_data, cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; free (cur); return 0 ; } int llist_fetch (LLIST *h, const void *find_data, llist_cmp cmp, void *save) { struct llist_head *handler = h; struct llist_node *cur = NULL ; cur = _find(handler,find_data,cmp); if (cur == NULL ) return -1 ; cur->next->prev = cur->prev; cur->prev->next = cur->next; memcpy (save, cur->data, handler->size); free (cur); return 0 ; }
makefile 1 2 3 4 llist : main.o llist.o gcc -o $@ $^ clean : rm -rf *.o llist