Linux内核通用链表
链表的节点不能包含万物,那么就让万物包含节点。
仿照linux内核链表改写的链表
废话不多说,上代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define offset(type,mem) ((int)&((type*)0)->mem)
#define node_to_obj(node,type,mem) ((type*)((void*)node-offset(type,mem)))
// 遍历
#define list_for_each(n,head) \
for(n=head->next; n!=head; n=n->next)
#define list_for_each_entry(obj,head,mem)\
for(obj=node_to_obj(head->next,typeof(*obj),mem);\
&obj->mem!=head;\
obj=node_to_obj(obj->mem.next,typeof(*obj),mem))
// 链表节点
typedef struct Node
{
struct Node* prev;
struct Node* next;
}Node;
// 创建链表
Node* create_list(void)
{
Node* head = malloc(sizeof(Node));
head->prev = head;
head->next = head;
return head;
}
void _add_list(Node* prev,Node* next,Node* node)
{
next->prev = node;
node->next = next;
node->prev = prev;
prev->next = node;
}
// 头添加
void add_head_list(Node* head,Node* node)
{
_add_list(head,head->next,node);
}
// 尾添加
void add_tail_list(Node* head,Node* node)
{
_add_list(head->prev,head,node);
}
// 判断链表是否为空
bool empty_list(Node* head)
{
return head->next == head;
}
// 删除节点
void _del_list(Node* node)
{
node->next->prev = node->prev;
node->prev->next = node->next;
node->next = NULL;
node->prev = NULL;
}
// 头删除
Node* del_head_list(Node* head)
{
if(empty_list(head)) return NULL;
Node* node = head->next;
_del_list(node);
return node;
}
// 尾删除
Node* del_tail_list(Node* head)
{
if(empty_list(head)) return NULL;
Node* node = head->prev;
_del_list(node);
return node;
}
// 按位置删除
Node* del_index_list(Node* head,size_t index)
{
Node *node = head->next;
for(int i=0; i<index; i++)
{
node = node->next;
if(node == head) return NULL;
}
_del_list(node);
return node;
}
/*---------------------------------------*/
typedef struct Student
{
char name[20];
char sex;
Node node;
char age;
float score;
int id;
}Student;
int main(int argc,const char* argv[])
{
Node* head = create_list();
for(int i=0; i<10; i++)
{
Student* stu = malloc(sizeof(Student));
sprintf(stu->name,"hehe");
stu->sex = i%2?'w':'m';
stu->age = 18+i%2;
stu->score = rand()%100;
stu->id = 1001+i;
add_tail_list(head,&stu->node);
printf("%s %c %hhd %g %d\n",stu->name,stu->sex,stu->age,stu->score,stu->id);
}
Node* temp = del_index_list(head,8);
free(node_to_obj(temp,Student,node));
/*
Node* temp = del_tail_list(head);
free(node_to_obj(temp,Student,node));
temp = del_tail_list(head);
free(node_to_obj(temp,Student,node));
temp = del_tail_list(head);
free(node_to_obj(temp,Student,node));
temp = del_head_list(head);
free(node_to_obj(temp,Student,node));
temp = del_head_list(head);
free(node_to_obj(temp,Student,node));
*/
printf("-------------------------\n");
Student* stu = NULL;
list_for_each_entry(stu,head,node)
{
printf("%s %c %hhd %g %d\n",stu->name,stu->sex,stu->age,stu->score,stu->id);
}
}