通用链表
能够存储任意类型的数据到链表中,并提供对应的操作
万能指针 void*
C语言中任意类型的指针可以转换成void*类型
void*类型指针可以转换成任意类型指针
- 节点:
void* ptr; // 数据域
指针域;
- 链表结构:
头指针
数量
- 核心点:
1、void* 确保能存储任意类型数据
2、普通操作可参考双链表即可
2、通过回调模式来实现一些特殊操作,例如:遍历、按值操作、排序
- list.h
#ifndef LIST_H
#define LIST_H
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
// 函数指针的类型重定义
typedef int (*CMP)(const void*,const void*);
typedef void (*SHOW)(const void*);
typedef void (*CHANGE)(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_head_list(List* list,const void* ptr);
// 尾添加
void add_tail_list(List* list,const void* ptr);
// 插入
bool insert_list(List* list,size_t index,const void* ptr);
// 按位置删除
void* del_index_list(List* list,size_t index);
// 按值删除
void* del_value_list(List* list,const void* ptr,CMP cmp);
// 按位置修改
bool mod_index_list(List* list,size_t index,const void* data,CHANGE change);
// 按值修改
bool mod_value_list(List* list,const void* old,CMP cmp,const void* data,CHANGE change);
// 访问
void* access_list(List* list,size_t index);
// 查询
void* query_list(List* list,const void* data,CMP cmp);
// 数量
size_t size_list(List* list);
// 排序
void sort_list(List* list,CMP cmp);
// 清空
void clear_list(List* list); // 节点、数据都删
// 销毁
void destroy_list(List* list);
// 遍历
void show_list(List* list,SHOW show);
#endif//LIST_H
- list.c
#include "list.h"
// 创建节点
static Node* create_node(const void* ptr)
{
Node* node = malloc(sizeof(Node));
node->ptr = (void*)ptr;
node->prev = node;
node->next = node;
return node;
}
// 两个节点之间添加一个新节点
static void _add_node(Node* p,Node* n,const void* ptr)
{
Node* node = create_node(ptr);
p->next = node;
n->prev = node;
node->prev = p;
node->next = n;
}
// 删除节点
static void _del_node(Node* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
free(node);
}
// 根据位置访问节点
static Node* _index_list(List* list,size_t index)
{
if(index >= list->size) return NULL;
if(index < list->size/2)
{
Node* n = list->head->next;
while(index--) n = n->next;
return n;
}
else
{
Node* n = list->head->prev;
while(++index < list->size) n = n->prev;
return n;
}
}
// 创建链表
List* create_list(void)
{
List* list = malloc(sizeof(List));
list->head = create_node(NULL); // 带头节点
list->size = 0;
return list;
}
// 头添加
void add_head_list(List* list,const void* ptr)
{
_add_node(list->head,list->head->next,ptr);
list->size++;
}
// 尾添加
void add_tail_list(List* list,const void* ptr)
{
_add_node(list->head->prev,list->head,ptr);
list->size++;
}
// 插入
bool insert_list(List* list,size_t index,const void* ptr)
{
Node* node = _index_list(list,index);
if(NULL == node) return false;
_add_node(node->prev,node,ptr);
list->size++;
return true;
}
// 按位置删除
void* del_index_list(List* list,size_t index)
{
Node* node = _index_list(list,index);
if(NULL == node) return NULL;
void* ptr = node->ptr;
_del_node(node);
list->size--;
return ptr;
}
// 按值删除
void* del_value_list(List* list,const void* ptr,CMP cmp)
{
for(Node* n=list->head->next; n!=list->head; n=n->next)
{
if(0 == cmp(n->ptr,ptr))
{
void* ptr = n->ptr;
_del_node(n);
list->size--;
return ptr;
}
}
return NULL;
}
// 遍历
void show_list(List* list,SHOW show)
{
for(Node* n=list->head->next; n!=list->head; n=n->next)
{
show(n->ptr);
}
}
// 按位置修改
bool mod_index_list(List* list,size_t index,const void* data,CHANGE change)
{
Node* node = _index_list(list,index);
if(NULL == node) return false;
change(node->ptr,data);
return true;
}
// 按值修改
bool mod_value_list(List* list,const void* old,CMP cmp,const void* data,CHANGE change)
{
for(Node* n=list->head->next; n!=list->head; n=n->next)
{
if(0 == cmp(n->ptr,old))
{
change(n->ptr,data);
return true;
}
}
return false;
}
// 访问
void* access_list(List* list,size_t index)
{
Node* node = _index_list(list,index);
if(NULL == node) return NULL;
return node->ptr;
}
// 查询
void* query_list(List* list,const void* data,CMP cmp)
{
for(Node* n=list->head->next; n!=list->head; n=n->next)
{
if(0 == cmp(n->ptr,data)) return n->ptr;
}
return NULL;
}
// 数量
size_t size_list(List* list)
{
return list->size;
}
// 排序
void sort_list(List* list,CMP 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* temp = n->ptr;
n->ptr = m->ptr;
m->ptr = temp;
}
}
}
}
// 清空
void clear_list(List* list)
{
while(list->size--)
{
void* ptr = del_index_list(list,0);
free(ptr);
}
}
// 销毁
void destroy_list(List* list)
{
clear_list(list);
free(list->head);
free(list);
}
标签:node,index,通用,List,void,list,链表,封装,ptr
From: https://www.cnblogs.com/ljf-0804/p/17689735.html