04ds_05day

04ds_05day

==============================
2022-8-5
==============================

note

一.早测
    完成有头双向循环链表的功能
    1.创建头结点
    2.插入数据结点
    3.遍历链表
    4.销毁链表
    5.查找结点
    6.删除结点
    7.拿出结点
只写声明和实现,不用写调用(llist.c 和 llist.h)

=================================
作业
1.把这一周讲过的内容都完完整整的复习一遍
2.把三个版本的通用性强的链表重新实现一遍
3.在纸上写链表的代码
=================================

通用性强的链表

结点图
resources/结点图.png

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;//handler指针指向头结点
	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;//创建失败,结束程序,并且返回-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");
/*	
	find = llist_find(handler, &find_tel, tel_cmp);//查找
	if(find == NULL)//判断是否没有找到
		printf("Not Find It!\n");
	else
	{
		printf("Find It!\n");
		print(find);
	}
*/
#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;//data指针指向数据
	struct llist_node *prev;//prev指针指向前驱
	struct llist_node *next;//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;//开辟失败,结束函数,并且返回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;//开辟失败,结束函数,并且返回-1
	
	newnode->data=malloc(handler->size);//开辟数据空间
	if(newnode->data == NULL)//判断数据空间是否开辟失败
	{
		free(newnode);//释放数据结点的空间
		return -2;//数据空间开辟失败,结束函数,并且返回-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指针已经指向要删除的结点
	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));//开辟16byte空间
	newnode = malloc(sizeof(struct bbb) + 40);//开辟56byte空间

	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;//handler指针指向头结点
	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;//创建失败,结束程序,并且返回-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");
/*	
	find = llist_find(handler, &find_tel, tel_cmp);//查找
	if(find == NULL)//判断是否没有找到
		printf("Not Find It!\n");
	else
	{
		printf("Find It!\n");
		print(find);
	}
*/
#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;//prev指针指向前驱
	struct llist_node *next;//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;//开辟失败,结束函数,并且返回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;//开辟失败,结束函数,并且返回-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指针已经指向要删除的结点
	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;//handler指针指向头结点
	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;//创建失败,结束程序,并且返回-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");
/*	
	find = llist_find(handler, &find_tel, tel_cmp);//查找
	if(find == NULL)//判断是否没有找到
		printf("Not Find It!\n");
	else
	{
		printf("Find It!\n");
		print(find);
	}
*/
#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;//prev指针指向前驱
	struct llist_node *next;//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;//开辟失败,结束函数,并且返回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;//开辟失败,结束函数,并且返回-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指针已经指向要删除的结点
	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