代码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;
}
运行结果: