Linux内核链表

5 篇文章 0 订阅

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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值