通用链表-C语言

list.h

#ifndef LIST_H
#define LIST_H

#include <stdbool.h>

//	类型重定义函数指针
typedef int (*Compar)(const void*,const void*);

//	链表节点
typedef struct Node
{
	void* ptr;	//数据域
	struct Node* prev;
	struct Node* next;
}Node;

//	通用链表结构
typedef struct List
{
	Node* head;
	size_t size;
}List;

//	创建链表
List* create_list(void);

//	添加
void add_list(List* list,void* ptr);

//	插入
bool insert_list(List* list,size_t index,void* ptr);
//	删除 位置
bool del_index_list(List* list,size_t index);
//	删除 值
bool del_value_list(List* list,void* ptr,Compar cmp);
//	查询
void* qurey_list(List* list,void* ptr,Compar cmp);
//	访问
void* visit_list(List* list,size_t index);
//	排序
void sort_list(List* list,Compar cmp);
//	清空
void clean_list(List* list);
//	销毁
void destory_list(List* list);
//	遍历
void show_list(List* list,void (*show)(void* ));

#endif//LIST_H

list.c

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "list.h"

//	创建节点
static Node* create_node(void* ptr)
{
	Node* node = malloc(sizeof(Node));
	node->ptr = ptr;
	node->prev = node;
	node->next = node;
	return node;
}

//	两个节点之间插入一个新节点
static void _add_list(Node* prev,Node* next,void* ptr)
{
	Node* node = create_node(ptr);
	prev->next = node;
	next->prev = node;
	node->prev = prev;
	node->next = next;
}

//	删除节点
static void _del_list(Node* node)
{
	node->prev->next = node->next;
	node->next->prev = node->prev;
	free(node->ptr);
	free(node);
}

//	根据位置访问节点
static Node* _visit_list(List* list,size_t index)
{
	if(index >= list->size)	return NULL;
	if(index < list->size/2) 
	{
		Node* node = list->head->next;
		while(index--)	node = node->next;
		return node;
	}
	else
	{
		Node* node = list->head->prev;
		while(++index < list->size) node = node->prev;
		return node;
	}
}

//	创建链表
List* create_list(void)
{
	List* list = malloc(sizeof(List));
	list->head = create_node(0);
	list->size = 0;
	return list;
}

//	添加 尾添加
void add_list(List* list,void* ptr)
{
	_add_list(list->head->prev,list->head,ptr);
	list->size++;
}

//	插入
bool insert_list(List* list,size_t index,void* ptr)
{
	Node* node = _visit_list(list,index);
	if(NULL == node)	return false;
	
	_add_list(node->prev,node,ptr);
	list->size++;
	return true;
}

//	删除 位置
bool del_index_list(List* list,size_t index)
{
	Node* node = _visit_list(list,index);
	if(NULL == node) return false;

	_del_list(node);
	list->size--;
	return true;
}

//	删除 值
//bool del_value_list(List* list,void* ptr,int (*cmp)(const void*,const void*))
bool del_value_list(List* list,void* ptr,Compar cmp)
{
	for(Node* n=list->head->next; n!=list->head; n=n->next)
	{
		if(0 == cmp(ptr,n->ptr))
		{
			_del_list(n);
			list->size--;
			return true;
		}
	}
	return false;
}

//	查询
void* qurey_list(List* list,void* ptr,Compar cmp)
{
	for(Node* n=list->head->next; n!=list->head; n=n->next)
	{
		if(0 == cmp(ptr,n->ptr))
			return n->ptr;
	}
	return NULL;
}

//	访问
void* visit_list(List* list,size_t index)
{
	Node* node = _visit_list(list,index);
	if(NULL == node) return NULL;

	return node->ptr;
}

//	排序
void sort_list(List* list,Compar cmp)
{
	for(Node* n=list->head->next; n->next!=list->head; n=n->next)
	{
		for(Node* m=n->next; m!=list->head; m=m->next)
		{
			if(-1 == cmp(n->ptr,m->ptr))
			{
				void* tmp = n->ptr;
				n->ptr = m->ptr;
				m->ptr = tmp;
			}
		}
	}
}

//	清空
void clean_list(List* list)
{
	Node* node = list->head->next;
	while(list->size--)
	{
		Node* temp = node;
		node = node->next;
		free(temp->ptr);
		free(temp);
	}
	list->head->next = list->head;
	list->head->prev = list->head;
}

//	销毁
void destory_list(List* list)
{
	clean_list(list);
	free(list->head->ptr);
	free(list->head);
	free(list);
}

//	遍历
void show_list(List* list,void (*show)(void* ))
{
	for(Node* n=list->head->next; n!=list->head; n=n->next)
	{
		show(n->ptr);
	}
}

测试test.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"

//	此文件是调用者写的代码

typedef struct Student
{
	char name[20];
	char sex;
	int id;
}Student;

	
//	打印结构体的回调函数由调用者提供
void show_stu(void* ptr)
{
	Student* stu = ptr;
	printf("姓名:%s 性别:%c 学号:%d\n",stu->name,stu->sex,stu->id);
}

//	结构体比较函数也是由调用者提供的回调函数
int stucmp(const void* s1,const void* s2)
{
	const Student* stu1 = s1;
	const Student* stu2 = s2;
	if(stu1->id > stu2->id)
		return -1;
	if(stu1->id < stu2->id)
		return 1;
	return 0;
}

int main(int argc,const char* argv[])
{
	List* list = create_list();
	for(int i=0; i<10; i++)
	{
		Student* stu = malloc(sizeof(Student));
		strcpy(stu->name,"hehe");
		stu->sex = i%2?'w':'m';
		stu->id = 1001+i;
		add_list(list,stu);
	}
	show_list(list,show_stu);

	printf("-------------\n");
	Student stu = {"xixi",'w',1011};
	//del_value_list(list,&stu,stucmp);
	//insert_list(list,10,&stu);
	//del_index_list(list,9);
//	show_stu(qurey_list(list,&stu,stucmp));
	//sort_list(list,stucmp);
//	show_list(list,show_stu);
	clean_list(list);
	for(int i=0; i<10; i++)
	{
		Student* stu = malloc(sizeof(Student));
		strcpy(stu->name,"hehe");
		stu->sex = i%2?'w':'m';
		stu->id = 1001+i;
		add_list(list,stu);
	}
	show_list(list,show_stu);
	destory_list(list);
	for(int i=0; i<10; i++)
	{
		Student* stu = malloc(sizeof(Student));
		strcpy(stu->name,"hehe");
		stu->sex = i%2?'w':'m';
		stu->id = 1001+i;
		add_list(list,stu);
	}
	show_list(list,show_stu);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值