c语言:通用链表

在以后的代码生涯中肯定不会缺少链表的使用,为了使用方便,可以制作一个通用链表。
以下为通用双向链表

//定义两个函数指针比较CMP 显示SHOW 由用户编写
typedef int (*CMP)(const void*,const void*);
typedef void (*SHOW)(const void*);
//结点结构体
typedef struct Node
{
	void* data;				//数据位
	struct Node* prev;	//前结点
	struct Node* next;	//后结点
}Node;
//创建结点
Node* create_node(void* data)
{
	Node* node = malloc(sizeof(Node));
	node->data = data;
	node->prev = node;	
	node->next = node;
	return node;
}
//链表结构体
typedef struct List
{
	Node* head;
	size_t size; //链表长度
}List;
//创建链表
List* create_list(void)
{
	List* list = malloc(sizeof(List));
	list->head = create_node(0);
	list->size = 0;
	return list;
}
//判断链表空
bool empty_list(List* list)
{
	return list->head == list->head->next;
}
//添加结点子函数
void _add_node(Node* prev,Node* next,void* data)
{
	Node* node = create_node(data);
	//链接前后结点
	node->next = prev->next;
	node->prev = next->prev;
	prev->next = node;
	next->prev = node;
}
//添加结点 头添加
void* add_head_list(List* list,void* data)
{
	_add_node(list->head,list->head->next,data);
	list->size++;
}
//添加结点 尾添加
void* add_tail_list(List* list,void* data)
{
	_add_node(list->head->prev,list->head,data);
	list->size++;
}
//删除结点子函数
void _del_node(Node* node)
{
	//待删除结点前后结点连接(隔离此结点)
	Node* prev = node->prev;
	Node* next = node->next;
	prev->next = next;
	next->prev = prev;
	free(node->data);	//释放内存
	free(node);
}
//头删除结点
bool del_head_list(List* list)
{
	if(list->head->next == list->head)
		return false;
	_del_node(list->head->next);
	list->size--;
	return true;
}
//尾删除结点
bool del_tail_list(List* list)
{
	if(list->head->prev == list->head)
		return false;
	_del_node(list->head->prev);
	list->size--;
	return true;	
}
//按值查询子函数
Node* _query_list(List* list,void* data,CMP cmp)
{
	Node* n = list->head->next;
	while(list->head != n)	//遍历比较
	{
		if(0 == cmp(n->data,data))
			return n;
		n=n->next;
	}
	return NULL;
}
//按位查询子函数
Node* _index_list(List* list,size_t index)
{
	if(index < list->size/2)	//从头向后遍历
	{
		Node* n = list->head->next;
		while(index)
		{
			n = n->next;
			index--;
		}
		return n;
	}
	else									//从尾向前遍历
	{
		Node* n = list->head->prev;
		index = list->size - index - 1;
		while(index)
		{
			n = n->prev;
			index--;
		}
		return n;
	}
}
//按位删除
bool del_index_list(List* list,size_t index)
{
	if(0 == list->size || index >= list->size)
		return false;
	Node* N = _index_list(list,index);
	_del_node(N);
	list->size--;
	return true;
}
//按值删除
bool del_value_list(List* list,void* data,CMP cmp)
{
	Node* n = _query_list(list,data,cmp);
	if(NULL == n)
		return NULL;
	data = n->data;
	_del_node(n);
	list->size--;
	return true;
}
//按位修改
bool modify_index_list(List* list,size_t index,void* data)
{
	Node* n = _index_list(list,index);
	if(NULL == n)
		return false;
	n->data = data;
	return true;
}
//遍历显示
void show_list(List* list,SHOW show)
{
	for(Node* n=list->head->next; n!=list->head; n=n->next)
	{
		show(n->data);
	}
	printf("\n");
	/*
	for(Node* n=list->head->prev; n!=list->head; n=n->prev)
	{
		show(n->data);
	}
	printf("\n");
	*/
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值