内核链表

代码demon

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define SIZE 20

struct dl_list {
	struct dl_list *next;
	struct dl_list *prev;
};

//初始化链表,前驱等于后继
static inline void dl_list_init(struct dl_list *list)
{
	list->next = list;
	list->prev = list;
}

//参数二是要插入的节点,参数一是链表头
static inline void dl_list_add(struct dl_list *list, struct dl_list *item)
{
	item->next = list->next;
	item->prev = list;
	list->next->prev = item;
	list->next = item;
}

//尾插,在表头的前一个节点插入,表头前一个节点就是尾节点
static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
{
	dl_list_add(list->prev, item);
}

//删除某个节点
static inline void dl_list_del(struct dl_list *item)
{
	item->next->prev = item->prev;
	item->prev->next = item->next;
	item->next = NULL;
	item->prev = NULL;
}

//判断链表是否为空,头等于尾返回1,证明为空
static inline int dl_list_empty(struct dl_list *list)
{
	return list->next == list;
}

//判断链表的长度
static inline unsigned int dl_list_len(struct dl_list *list)
{
	struct dl_list *item;
	int count = 0;
	for (item = list->next; item != list; item = item->next)//头不等于尾
		count++;
	return count;
}



#ifndef offsetof
#define offsetof(type, member) ((long) &((type *) 0)->member) //结构体偏移
#endif

/****************************************************************
*item指向的链表节点所在的type类型的结构体首地址,member是结构体成员
获取头节点的地址
******************************************************************/
#define dl_list_entry(item, type, member) \
	((type *) ((char *) item - offsetof(type, member))) 

/*****************************************
**获取链表的第一个节点
******************************************/
#define dl_list_first(list, type, member) \
	(dl_list_empty((list)) ? NULL : \
	 dl_list_entry((list)->next, type, member))

//获取链表的最后一个结构体
#define dl_list_last(list, type, member) \
	(dl_list_empty((list)) ? NULL : \
	 dl_list_entry((list)->prev, type, member))

/**************************************************************
**遍历链表
**参数1:存放遍历出来的数据  参数2:遍历的链表
**参数3:遍历结构体的类型    参数4:遍历结构体的方向指针
****************************************************************/
#define dl_list_for_each(item, list, type, member) \
	for (item = dl_list_entry((list)->next, type, member); \
	     &item->member != (list); \
	     item = dl_list_entry(item->member.next, type, member))

#define dl_list_for_each_safe(item, n, list, type, member) \
	for (item = dl_list_entry((list)->next, type, member), \
		     n = dl_list_entry(item->member.next, type, member); \
	     &item->member != (list); \
	     item = n, n = dl_list_entry(n->member.next, type, member))
	     
/*********************************
**链表倒置
**********************************/
#define dl_list_for_each_reverse(item, list, type, member) \
	for (item = dl_list_entry((list)->prev, type, member); \
	     &item->member != (list); \
	     item = dl_list_entry(item->member.prev, type, member))

//定义一个链表
#define DEFINE_DL_LIST(name) \
	struct dl_list name = { &(name), &(name) }

#define LIST_HEAD_INIT(name) { &(name), &(name) }


typedef struct 
{
	char name[SIZE];
	int age;
	int score;
	struct dl_list node;
}Student;

Student *init(int a,int s,char* name)
{
	Student *stu = malloc(sizeof(Student));
	stu->age=a;
	stu->score=s;
	strcpy(stu->name,name);
	return stu;
}

//插入数据
void insert(struct dl_list *list,int a,int s,char *name)
{
	Student *s_init=init(a,s,name);
	dl_list_add_tail(list, &s_init->node);//尾插
}

//打印输出
void display(struct dl_list *list)
{
	Student *stu;
	dl_list_for_each(stu, list, Student, node)
	{
		printf("name:%s| age:%d|, score=%d\n",stu->name,stu->age,stu->score);
	}
}

int main()
{

//1.初始化定义一个链表
	DEFINE_DL_LIST(head);


//2.插入操作
	printf("1-空  0-非空|value is %d\n",dl_list_empty(&head));

	insert(&head,18,85,"小明");
	insert(&head,18,90,"甲");
	insert(&head,18,91,"乙");
	insert(&head,18,85,"丙");	
	display(&head);

//2.删除操作
	Student *stu;
	Student *tmp;
	dl_list_for_each_safe(stu, tmp,&head,Student, node)
	{
		//printf("stu->name is %s \n",stu->name);
		if(0==strcmp(stu->name,"小明"))//查询
		{
			dl_list_del(&stu->node);//删除
			free(stu);
		}
	}
	printf("\ndelet after:\n");
	display(&head);

//修改
	dl_list_for_each_safe(stu, tmp,&head,Student, node)
	{
		if(0==strcmp(stu->name,"甲"))
		{
			strcpy(stu->name,"小红");
		}
	}
	printf("\nchange after:\n");
	display(&head);

//链表倒置
	printf("\nreverse after:\n");
	Student *stu1;
	dl_list_for_each_reverse(stu1, &head, Student, node)
	{
		printf("name:%s| age:%d|, score=%d\n",stu1->name,stu1->age,stu1->score);
	}

//获取链表第一个结构体信息
	Student *stu2=dl_list_first(&head,Student,node);
	printf("\nfirst is name:%s| age:%d|, score=%d\n",stu2->name,stu2->age,stu2->score);

//获取链表的最后一个结构体信息
	Student *stu3=dl_list_last(&head, Student, node);
	printf("\nlast is name:%s| age:%d|, score=%d\n",stu3->name,stu3->age,stu3->score);

//链表长度
	printf("链表长度 is %d \n",dl_list_len(&head));

//清空链表
	printf("1-空  0-非空|value is %d\n",dl_list_empty(&head));


	return 0;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值