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;
}
}