在以后的代码生涯中肯定不会缺少链表的使用,为了使用方便,可以制作一个通用链表。
以下为通用双向链表
//定义两个函数指针比较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");
*/
}