linux内核链表(亲测可用)

Linux内核链表

头文件:

#ifndef _LIST_H
#define _LIST_H
//#include<stdio.h>
//#include<stdlib.h>
struct list_head {
	struct list_head *next, *prev;
};

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

#define LIST_HEAD(name) \
	struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}

static inline void __list_add(struct list_head *node,struct list_head *prev,struct list_head *next)
{
	next->prev = node;
	node->next = next;
	node->prev = prev;
	prev->next = node;
}

static inline void list_add(struct list_head *node, struct list_head *head)
{
	__list_add(node, head, head->next);
}

static inline void list_add_tail(struct list_head *node, struct list_head *head)
{
	__list_add(node, head->prev, head);
}

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}

static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
}

static inline void __list_del_entry(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
}

static inline void list_del_init(struct list_head *entry)
{
	__list_del_entry(entry);
	INIT_LIST_HEAD(entry);
}

static inline void list_replace(struct list_head *old,struct list_head *node)
{
	node->next = old->next;
	node->next->prev = node;
	node->prev = old->prev;
	node->prev->next = node;
}

static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({          \
			const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
			(type *)( (char *)__mptr - offsetof(type,member) );})
//pos是小结构体指针,向后遍历,pos类型是struct list_head *,head是内核链表的头指针,也是小结构体指针
#define list_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); pos = pos->next)

#define list_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
				pos = n, n = pos->next)

#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

#endif

主程序:

#include<stdio.h>
#include "list.h"
#include<stdlib.h>
#include<string.h>
/* 
struct list_head {
	struct list_head *next, *prev;
};
*/
typedef struct stu{
	int age;
	char name[30];
	struct list_head mbr;
}Stu,*Stedu;
//函数声明
void show_klist(Stu *phead);
//初始化
Stedu init_klist(void)
{
	Stu *phead=(Stu *)malloc(sizeof(Stu));
	if(phead==NULL)
	{
		return phead;
	}
	INIT_LIST_HEAD(&(phead->mbr));		//static inline void INIT_LIST_HEAD(struct list_head *list)
	return phead;
}
//弄一个新节点,返回大结构体地址
Stedu make_node(char *name,int ge)//char name[]
{
	Stu *pnew=(Stu *)malloc(sizeof(Stu));
	if(pnew==NULL)
		return pnew;
	pnew->age=ge;
	strncpy(pnew->name,name, sizeof(pnew->name) - 1);
	INIT_LIST_HEAD(&(pnew->mbr));
	return pnew;
}
//插入
bool insert_knode_tail(Stu *phead,Stu *pnew)
{
/* 	
    pnew->mbr.next=&(phead->mbr);
	pnew->mbr.prev=phead->mbr.prev;
	phead->mbr.prev->next=&(pnew->mbr);
	phead->mbr.prev=&(pnew->mbr); 
*/
    list_add_tail(&(pnew->mbr), &(phead->mbr));     //static inline void list_add_tail(struct list_head *new, struct list_head *head)
	return true;
}

//表长
int ListLength(Stu *L)
{
	struct list_head  *pos;
	if (NULL == L)
		return -1;
	Stu *q=L;
	Stu *y=NULL;
	int i=0;
	list_for_each(pos,&(q->mbr))//循环
	{
		i++;
	}
	return i;
}
//按位插入
void insert_list(Stu *phead,int i)
{
	if(i>=ListLength(phead)||i<0)//此处特殊,本来应为i>ListLength(phead)||i<=0,但是下面插入在前面,所以……
	{
		printf("插入位置有误,插入失败\n");
		return;
	}
	Stu *l=phead;
	int j=0;
	struct list_head  *pos;
	pos=phead->mbr.next;
	Stu *q=(Stu *)malloc(sizeof(Stu));
	printf("输入姓名:\n");
	char name5[30];
	scanf("%s",name5);
	printf("输入年龄:\n");
	int y;
	scanf("%d",&y);
	strncpy(q->name,name5,sizeof(q->name)-1);//strncpy(pnew->name,name, sizeof(pnew->name) - 1);
	q->age=y;
	list_for_each(pos,&(phead->mbr))
	{
			Stu *p=list_entry(pos,struct stu,mbr);//p为大结构体首地址
			if((strcmp(q->name,p->name)==0)&&(q->age==p->age))
			{
				printf("此用户已经存在,插入失败!\n");
				free(q);
				printf("目前名单为:\n");
				printf("--------------------\n");	
				show_klist(l);
				printf("--------------------\n");
				return;
			}
	}
	pos=phead->mbr.next;
	while(j<i)
	{
		pos=pos->next;
		j++;
	}
	Stu *m=list_entry(pos,struct stu,mbr);
    q->mbr.next=&(m->mbr);
	q->mbr.prev=m->mbr.prev;
	m->mbr.prev->next=&(q->mbr);
	m->mbr.prev=&(q->mbr);
	printf("插入成功,目前名单为:\n");
    printf("--------------------\n");	
	show_klist(l);
	printf("--------------------\n");
}
//遍历内核链表
void show_klist(Stu *phead)
{
	struct list_head  *pos;
	Stu *p=NULL;
	list_for_each(pos,&(phead->mbr))
	{
		p=list_entry(pos,struct stu,mbr);//p为大结构体首地址
		printf("%s,%d\n",p->name,p->age);
	}
}
//删除
void del_list(char *name,Stu *p,int v)
{
	struct list_head  *pos;
	Stu *q=p;
	Stu *y=NULL;
	list_for_each(pos,&(q->mbr))//循环
	{
		y=list_entry(pos,struct stu,mbr);//返回大结构体指针
		if((strcmp(name,y->name)==0)&&(y->age==v))
		{
			list_del(pos);
			printf("删除成功,剩余名单为:\n");
			free(y);
			return;
		}
	}
	printf("删除失败,不存在您输入的姓名或姓名对应年龄有误,目前名单为:\n");
}
//改
void change_list(Stu *p,char *name,int w)//p=phead
{
	struct list_head  *pos;
	Stu *q=p;
	Stu *y=NULL;
	Stu *o=NULL;
	list_for_each(pos,&(q->mbr))//循环
		{
			y=list_entry(pos,struct stu,mbr);//返回大结构体指针
			if((strcmp(name,y->name)==0)&&(y->age==w))
	     	{
				char name2[30];
				printf("请输入您想改为的名字\n");
				scanf("%s",&name2);
				//strcpy(y->name,name2);
				int b;
				printf("请输入您想改为的年龄\n");
				scanf("%d",&b);
				//y->age=b;
				list_for_each(pos,&(q->mbr))//循环
				{
					o=list_entry(pos,struct stu,mbr);//返回大结构体指针
					if((strcmp(name2,o->name)==0)&&(o->age==b))
					{
						printf("此用户存在,更改失败,名单为:\n");
						printf("--------------------\n");
						show_klist(p);
						printf("--------------------\n");
						return;
					}
				}
				strcpy(y->name,name2);
				y->age=b;
				printf("更改成功,名单为:\n");
				printf("--------------------\n");
				show_klist(p);
				printf("--------------------\n");
				return;
		    }
		}
	printf("更改失败,不存在您输入的姓名或姓名对应年龄有误,目前名单为:\n");
	printf("--------------------\n");
	show_klist(p);
	printf("--------------------\n");
}
//按姓名查
void seek_list(Stu *p,char *name)
{
	struct list_head  *pos;
	Stu *q=p;
	Stu *y=NULL;
	int flag=0;
	list_for_each(pos,&(q->mbr))//循环
	{
		y=list_entry(pos,struct stu,mbr);//返回大结构体指针
		if(strcmp(name,y->name)==0)
		{
			printf("您查询的名字是%s,年龄为%d\n",y->name,y->age);
			flag=1;
		}
	}
	if(flag==0)
	{
		printf("查找失败,不存在您输入姓名!\n");
	}
}
//按年龄查
void seek_list1(Stu *p,int ag)
{
	struct list_head  *pos;
	Stu *q=p;
	Stu *y=NULL;
	int flag=0;
	list_for_each(pos,&(q->mbr))//循环
	{
		y=list_entry(pos,struct stu,mbr);//返回大结构体指针
		if(y->age==ag)
		{
			printf("您查询的名字是%s,年龄为%d\n",y->name,y->age);
			flag=1;
		}
	}
	if(flag==0)
	{
		printf("查找失败,不存在您输入年龄!\n");
	}
}
//清除
void clean_list(Stu *head)
{
	struct list_head  *pos;
	Stu *q=NULL;
	Stu *y=NULL;
	pos=head->mbr.next;
	y=list_entry(pos,struct stu,mbr);//返回大结构体指针
    int a=ListLength(head);
	for(int i=0;i<a;i++)
	{
		q=y;
		pos=pos->next;
		y=list_entry(pos,struct stu,mbr);
		free(q);
	}
	free(head);
}
//主函数
int main()
{
	while(1)
	{
	Stedu phead=init_klist();//初始化,phead是头指针
	//Stedu q=NULL;
	//q=make_node("Tom",18);
	//insert_knode_tail(phead,q);
    show_klist(phead);
	int x;
	int a;
	char name1[30];
	while(1)
	{
		printf("输入请按1,结束请按-1:\n");
		scanf("%d",&x);
		if(x==-1)
		{
			printf("目前名单为:\n");
			printf("--------------------\n");
			show_klist(phead);
			printf("--------------------\n");
			break;
		}
		Stedu w=NULL;
		printf("请输入姓名:\n");
		scanf("%s",name1);
		printf("请输入年龄:\n");
		scanf("%d",&a);
		w=make_node(name1,a);//w为新节点指针
		struct list_head  *po;
		Stu *p=NULL;
		int flag=0;
		list_for_each(po,&(phead->mbr))
		{
			p=list_entry(po,struct stu,mbr);//p为大结构体首地址
			if((strcmp(w->name,p->name)==0)&&(p->age==w->age))
			{
			printf("此用户已经存在,添加失败!\n");
			free(w);
			flag=1;
			}
		}
		if(flag==0)
		{
		insert_knode_tail(phead,w);
		printf("插入成功\n");
		}
		printf("目前的名单:\n");
		printf("--------------------\n");
		show_klist(phead);
		printf("--------------------\n");
		printf("==================================================================\n");	
	}
	//插入
	printf("按位插入,请输入在第几个位置插入数据:\n");
	int u;
	scanf("%d",&u);
	insert_list(phead,u-1);
	//删除
	int b;
	while(1)
	{
	printf("您想删除成员吗?(1 or -1)\n");
	scanf("%d",&b);
    if(b==-1)
	{
		printf("结束删除,目前名单为:\n");
		printf("--------------------\n");
		show_klist(phead);
		printf("--------------------\n");
	    break;
	}
	char name2[30];
	int c;
	printf("请输入想要删除的名字:\n");
	scanf("%s",name2);
	printf("年龄:\n");
	scanf("%d",&c);
	del_list(name2,phead,c);
	printf("--------------------\n");
	show_klist(phead);
	printf("--------------------\n");
	}
	//改
    char name3[30];
	int d;
    printf("请输入想要更改的人名\n");
	scanf("%s",name3);
	printf("请输入你想更改的年龄\n");
	scanf("%d",&d);
	change_list(phead,name3,d);
	//查
	int e;
	printf("按名字查找(1),按年龄查找(2)\n");
	scanf("%d",&e);
	if(e==1)
	{
		printf("请输入查询的名字\n");
		char name4[30];
		scanf("%s",name4);
		seek_list(phead,name4);
	}
	if(e==2)
	{
	printf("请输入查询的年龄\n");
	int f;
	scanf("%d",&f);
	seek_list1(phead,f);
	}
	clean_list(phead);
	printf("##################################################################\n");
	printf("您是否继续程序:继续(1) 结束(-1)\n");
	int g;
	scanf("%d",&g);
	if(g==-1)
		break;
	}	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值