==============================
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
|