已经重新整理,并且拆分成多文件,阅读更方便
函数众多都只是简单测试了,不保证没有BUG 有兴趣的可以拷贝下来测试
众所周知list是C++中的,但c没有所以就写了这个,尽量将名字都写成一样的,好方便后期使用
因为c没有模板这个概念,所以此代码为了实现所有数据类型,本身是无类型的,采用内存拷贝实现。
内置函数获取的数据都是以void指针的形式返回,需要强转成自己使用的类型。
目录
OneList* List_push_front(list* li, void* x);// 链表头部增加一个元素X
OneList* List_push_back(list* li, void* x);// 链表尾部增加一个元素X
void List_pop_front(list* li);//删除链表中第一个元素
void List_pop_back(list* li);//删除链表中最后一个元素
void List_clear(list* li);//清空list的队列,释放内存
void* List_at(const list* li, int i);// 想象成数组,输入下标返回元素的指针
void* List_front(list* li);//返回链表头指针,指向第一个元素
void* List_back(list* li);//返回链表尾指针,指向链表最后一个元素
void* List_find(const list* li, const void* val);//查找数据,返回找到的指针,没有返回NULL
bool List_empty(const list* li);//检测list内是否为空,空为真 O(1)
size_t List_size(const list* li);//返回list内元素的个数 O(1)
void List_sort(list* li, bool (*Sort)(void* x, void* y));//排序
void List_swap( list* li1, list* li2);//交换两个同类型链表的数据
void ListInitial(list* li, int n);//绑定函数指针到结构体
static void swap(void* x, void* y, const int n)//交换任意数据类型的函数
static OneList* find(const list* li, const void* val)//查找元素所在的节点,返回节点的指针
内置函数
插入函数
OneList* List_push_front(list* li, void* x);// 链表头部增加一个元素X
OneList* List_push_front(list* li, void* x)
{
OneList* p = List_push_back(li, x);
if (li->_current != 0)
{
li->_date = p;
}
return p;
}
OneList* List_push_back(list* li, void* x);// 链表尾部增加一个元素X
OneList* List_push_back(list* li, void* x)
{
OneList* p = malloc(sizeof(OneList));//开辟节点
if (p == NULL)
{
perror("开辟节点失败");
exit(-1);
}
p->data = malloc(li->_type);//开辟节点内储存数据的空间
memcpy(p->data, x, li->_type);//拷贝数据
if (li->_current == 0)
{
li->_date = p;
p->next = p;
p->prev = p;
}
else
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
p->next = pfront;
p->prev = pback;
pfront->prev = p;
pback->next = p;
}
li->_current++;
return p;
}
void List_insert_front(list* li, const void* p, ...);//list*li, const void* p, const void* x, const int n 链表中指向元素p前增加x元素n个,不填n默认1个(单次调用最多插入1000个,溢出均为1个)
void List_insert_front(list* li, const void* p, ...)
{
va_list args;//接收可变参数,
va_start(args, p);
void*x= va_arg(args,void*);//依次访问参数,需指定按照什么类型读取数据
int n= va_arg(args, int);
va_end(args);//参数使用结束
if (n > 1000 || n <= 0)//一次调用最多插入1000个
n = 1;
for (size_t i = 0; i < n; i++)
{
OneList* pval = find(li, p);
if (pval != NULL)
{
OneList* left = pval->prev;
//OneList* right = pval->next;
OneList* pk = malloc(sizeof(OneList));//开辟节点
if (pk == NULL)
{
perror("开辟节点失败");
exit(-1);
}
pk->data = malloc(li->_type);//开辟节点内储存数据的空间
memcpy(pk->data, x, li->_type);//拷贝数据
pk->prev = left;
pk->next = pval;
left->next = pk;
pval->prev = pk;
if (pval == li->_date)
{
li->_date = pk;
}
li->_current++;
}
else
{
perror("插入的数找不到");
}
}
}
void List_insert(list* li, const void* p, const void* p1, const void* p2);// 链表中指向元素p前插入另一个相同类型数组[p1,p2]间的数据,用指针传递数组
void List_insert(list* li, const void* p, const void* p1, const void* p2)
{
for (size_t i = 0; i < ((char*)p2-(char*)p1)/li->_type+1; i++)
{
List_insert_front(li, p,(char*)p1+i*li->_type);
}
}
删除函数
void List_pop_front(list* li);//删除链表中第一个元素
void List_pop_front(list* li)
{
if (li->_current == 1)
{
free(li->_date);
li->_date = NULL;
li->_current--;
}
else if(li->_current > 1)
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
OneList* pnfront = pfront->next;//新头节点
pnfront->prev = pback;
pback->next = pnfront;
li->_date = pnfront;
free(pfront);
li->_current--;
}
}
void List_pop_back(list* li);//删除链表中最后一个元素
void List_pop_back(list* li)
{
if (li->_current == 1)
{
free(li->_date);
li->_date = NULL;
li->_current--;
}
else if (li->_current > 1)
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
OneList* pnback = pback->prev;//新尾节点
pnback->next = pfront;
pfront->prev = pnback;
free(pback);//释放尾节点
li->_current--;
}
}
void List_erase_p( list* li, const void* p1, const void* p2);//删除指定元素区间内的数据(包括其本身),传入其指针地址,搭配find函数查找返回指针最佳,删除一个时请输入相同的指针
void List_erase_p(list* li, const void* p1, const void* p2)
{
OneList* p1O = find(li, p1);
OneList* p2O = find(li, p2);
OneList* pp=p1O;
OneList* left = p1O->prev;
OneList* right = p2O->next;
for (; pp != p2O; )
{
pp = pp->next;
free(pp->prev);
li->_current--;
}
free(pp);//释放p2O
li->_current--;
left->next = right;
right->prev = left;
if (p1O == li->_date)
{
li->_date = right;
}
}
void List_erase_int(list* li, const int left, const int right);//删除指定元素区间内的数据(包括其本身),将其想象成数组下标访问,输入要删除的下标,删除一个时请输入相同下标
void List_erase_int(list* li, const int left, const int right)
{
OneList* pleft=NULL ;
OneList* pright=NULL;
OneList* p=li->_date;
OneList* pp = p;
for (size_t i = 0; i <= right; i++)
{
p = p->next;
if (i >= left && i <= right)
{
if (i == left)
{
pleft = p->prev->prev;
}
if(i==right)
{
pright = p;
}
if (p == li->_date)
{
free(pp);
}
else
{
pp = p;
free(p->prev);
}
li->_current--;
}
}
pleft->next = pright;
pright->prev = pleft;
if (li->_current==0)
{
li->_date = NULL;
}
else if (left== 0)
{
li->_date = pright;
}
}
void List_clear(list* li);//清空list的队列,释放内存
void List_clear(list* li)
{
OneList* p = li->_date;
OneList* pnext = p->next;
for (size_t i = 0; i < li->_current; i++)
{
pnext = p->next;
free(p);
p = pnext;
}
li->_current = 0;
li->_date = NULL;
}
遍历函数
void* List_at(const list* li, int i);// 想象成数组,输入下标返回元素的指针
void* List_at(const list* li, int n)
{
if (n >= 0 && n < li->_current)
{
OneList* p = li->_date;
if (n == 0)
{
return p->data;
}
for (size_t j = 0; j < n; j++)
{
p = p->next;
}
return p->data;
}
return NULL;
}
void* List_front(list* li);//返回链表头指针,指向第一个元素
void* List_front(list* li)
{
return li->_date->data;
}
void* List_back(list* li);//返回链表尾指针,指向链表最后一个元素
void* List_back(list* li)
{
return li->_date->prev->data;
}
void* List_find(const list* li, const void* val);//查找数据,返回找到的指针,没有返回NULL
void* List_find(const list* li, const void* val)
{
return find(li, val)->data;
}
判断函数
bool List_empty(const list* li);//检测list内是否为空,空为真 O(1)
bool List_empty(const list* li)
{
return !li->_current;
}
大小函数
size_t List_size(const list* li);//返回list内元素的个数 O(1)
size_t List_size(const list* li)
{
return li->_current;
}
其他函数
void List_sort(list* li, bool (*Sort)(void* x, void* y));//排序
void List_sort(list* li, bool(*Sort)(void* x, void* y))
{
char* p1;//指向第一个元素
char* p2;
for (size_t n1 = 0; n1 <li->size(li)-1; n1++)
{
p1 = li->at(li, n1);
for (size_t n2 = n1+1; n2 <li->size(li); n2++)
{
p2 = li->at(li, n2);
if (!Sort(p1, p2))//排序比较函数,返回布尔值
{
swap(p1, p2, li->_type);//交换函数
}
}
}
}
void List_swap( list* li1, list* li2);//交换两个同类型链表的数据
void List_swap(list* li1, list* li2)
{
swap(&li1->_date,&li2->_date, sizeof(OneList*));
swap(&li1->_current, &li2->_current, sizeof(size_t));
}
初始化函数
void ListInitial(list* li, int n);//绑定函数指针到结构体
void ListInitial(list* li, int n)
{
li->push_front = List_push_front;
li->push_back = List_push_back;
li->insert_front = List_insert_front;
li->insert = List_insert;
li->at = List_at;
li->pop_front = List_pop_front;
li->pop_back = List_pop_back;
li->erase_p = List_erase_p;
li->erase_int = List_erase_int;
li->clear = List_clear;
li->at = List_at;
li->front = List_front;
li->back = List_back;
li->find = List_find;
li->empty = List_empty;
li->size = List_size;
li->sort = List_sort;
li->swap = List_swap;
li->_type = n;
li->_current = 0;
li->_date = NULL;
}
不对外公开函数
static void swap(void* x, void* y, const int n)//交换任意数据类型的函数
static void swap(void* x, void* y, const int n)//交换任意数据类型的函数
{
void* p = malloc(n);
if (p == NULL)
{
perror("交换函数创建p临时空间失败");
exit(-1);
}
memcpy(p, x, n);
memcpy(x, y, n);
memcpy(y, p, n);
free(p);
}
static OneList* find(const list* li, const void* val)//查找元素所在的节点,返回节点的指针
static OneList* find(const list* li, const void* val)//查找元素所在的节点,返回节点的指针
{
OneList* p = li->_date;
for (size_t i = 0; i < li->_current; i++)
{
if (memcmp(p->data, val, li->_type) == 0)
{
return p;
}
p = p->next;
}
return NULL;
}
测试结果
完整代码
list.h(头文件)
#pragma once
#define _CRT_SECURE_NO_DEPRECATE 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include <stdarg.h>
//一个节点
typedef struct OneList
{
struct OneList* prev;//指向上一个
struct OneList* next;//指向下一个
void* data;//储存的数据指针
}OneList;
typedef struct list
{
struct OneList * _date;//指向链表的头节点
size_t _current;//当前元素个数
size_t _type;//类型占用字节数
//插入函数
OneList* (*push_front)(struct list* li, void* x);//头插
OneList* (*push_back)(struct list* li, void* x);//尾插
void (*insert_front)(struct list*, const void* p, ...);//list*li, const void* p, const void* x, const int n 链表中指向元素p前增加x元素n个,不填n默认1个
void (*insert)(struct list*, const void* p, const void* p1, const void* p2);// 链表中指向元素p前插入另一个相同类型链表的指针[p1,p2)间的数据
//删除函数
void (*pop_front)(void*);//头删
void (*pop_back)(struct list*);//尾删
void (*erase_p)(struct list*, const void*, const void*);//删除指定元素区间内的数据(包括其本身),传入其指针地址,搭配find函数查找返回指针最佳,删除一个时请输入相同的指针
void (*erase_int)(struct list*, const int, const int);//删除指定元素区间内的数据(包括其本身),将其想象成数组下标访问,输入要删除的下标,删除一个时请输入相同下标
void (*clear) (struct list*);//清空list数据,释放内存
//遍历函数
void* (*at)(const struct list*, int);// 返回第0-n个元素的指针
void* (*front)(const struct list*);// 返回链表头指针,指向第一个元素
void* (*back)(const struct list*);//返回链表尾指针,指向链表最后一个元素
void* (*find)(const struct list*, const void*);//查找数据,返回找到的指针,没有返回NULL
//判断函数
bool (*empty)(const struct list*);// 检测list内是否为空,空为真 O(1)
//大小函数
size_t(*size)(const struct list*);//返回list内元素的个数 O(1)
//其他函数
void (*sort)(struct list*, bool (*Sort)(void*, void*));//排序
void (*swap)(struct list*, struct list*);//交换两个同类型链表的数据
}list;
//插入函数
OneList* List_push_front(list* li, void* x);// 链表头部增加一个元素X
OneList* List_push_back(list* li, void* x);// 链表尾部增加一个元素X
void List_insert_front(list* li, const void* p, ...);//list*li, const void* p, const void* x, const int n 链表中指向元素p前增加x元素n个,不填n默认1个
void List_insert(list* li, const void* p, const void* p1, const void* p2);// 链表中指向元素p前插入另一个相同类型数组[p1,p2]间的数据,数组传递用指针
//删除函数
void List_pop_front(list* li);//删除链表中第一个元素
void List_pop_back(list* li);//删除链表中最后一个元素
void List_erase_p( list* li, const void* p1, const void* p2);//删除指定元素区间内的数据(包括其本身),传入其指针地址,搭配find函数查找返回指针最佳,删除一个时请输入相同的指针
void List_erase_int(list* li, const int left, const int right);//删除指定元素区间内的数据(包括其本身),将其想象成数组下标访问,输入要删除的下标,删除一个时请输入相同下标
void List_clear(list* li);//清空list的队列,释放内存
//遍历函数
void* List_at(const list* li, int i);// 返回元素的指针
void* List_front(list* li);//返回链表头指针,指向第一个元素
void* List_back(list* li);//返回链表尾指针,指向链表最后一个元素
void* List_find(const list* li, const void* val);//查找数据,返回找到的指针,没有返回NULL
//判断函数
bool List_empty(const list* li);//检测list内是否为空,空为真 O(1)
//大小函数
size_t List_size(const list* li);//返回list内元素的个数 O(1)
//其他函数
void List_sort(list* li, bool (*Sort)(void* x, void* y));//排序
void List_swap( list* li1, list* li2);//交换两个同类型链表的数据
//初始化函数
void ListInitial(list* li, int n);
list.c(内置函数)
#include"list.h"
static void swap(void* x, void* y, const int n)//交换任意数据类型的函数
{
void* p = malloc(n);
if (p == NULL)
{
perror("交换函数创建p临时空间失败");
exit(-1);
}
memcpy(p, x, n);
memcpy(x, y, n);
memcpy(y, p, n);
free(p);
}
static OneList* find(const list* li, const void* val)//查找元素所在的节点,返回节点的指针
{
OneList* p = li->_date;
for (size_t i = 0; i < li->_current; i++)
{
if (memcmp(p->data, val, li->_type) == 0)
{
return p;
}
p = p->next;
}
return NULL;
}
OneList* List_push_front(list* li, void* x)
{
OneList* p = List_push_back(li, x);
if (li->_current != 0)
{
li->_date = p;
}
return p;
}
OneList* List_push_back(list* li, void* x)
{
OneList* p = malloc(sizeof(OneList));//开辟节点
if (p == NULL)
{
perror("开辟节点失败");
exit(-1);
}
p->data = malloc(li->_type);//开辟节点内储存数据的空间
memcpy(p->data, x, li->_type);//拷贝数据
if (li->_current == 0)
{
li->_date = p;
p->next = p;
p->prev = p;
}
else
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
p->next = pfront;
p->prev = pback;
pfront->prev = p;
pback->next = p;
}
li->_current++;
return p;
}
void List_insert_front(list* li, const void* p, ...)
{
va_list args;//接收可变参数,
va_start(args, p);
void*x= va_arg(args,void*);//依次访问参数,需指定按照什么类型读取数据
int n= va_arg(args, int);
va_end(args);//参数使用结束
if (n > 1000 || n <= 0)//一次调用最多插入1000个
n = 1;
for (size_t i = 0; i < n; i++)
{
OneList* pval = find(li, p);
if (pval != NULL)
{
OneList* left = pval->prev;
//OneList* right = pval->next;
OneList* pk = malloc(sizeof(OneList));//开辟节点
if (pk == NULL)
{
perror("开辟节点失败");
exit(-1);
}
pk->data = malloc(li->_type);//开辟节点内储存数据的空间
memcpy(pk->data, x, li->_type);//拷贝数据
pk->prev = left;
pk->next = pval;
left->next = pk;
pval->prev = pk;
if (pval == li->_date)
{
li->_date = pk;
}
li->_current++;
}
else
{
perror("插入的数找不到");
}
}
}
void List_insert(list* li, const void* p, const void* p1, const void* p2)
{
for (size_t i = 0; i < ((char*)p2-(char*)p1)/li->_type+1; i++)
{
List_insert_front(li, p,(char*)p1+i*li->_type);
}
}
void List_pop_front(list* li)
{
if (li->_current == 1)
{
free(li->_date);
li->_date = NULL;
li->_current--;
}
else if(li->_current > 1)
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
OneList* pnfront = pfront->next;//新头节点
pnfront->prev = pback;
pback->next = pnfront;
li->_date = pnfront;
free(pfront);
li->_current--;
}
}
void List_pop_back(list* li)
{
if (li->_current == 1)
{
free(li->_date);
li->_date = NULL;
li->_current--;
}
else if (li->_current > 1)
{
OneList* pfront = li->_date;//原头节点
OneList* pback = pfront->prev;//原尾节点
OneList* pnback = pback->prev;//新尾节点
pnback->next = pfront;
pfront->prev = pnback;
free(pback);//释放尾节点
li->_current--;
}
}
void List_erase_p(list* li, const void* p1, const void* p2)
{
OneList* p1O = find(li, p1);
OneList* p2O = find(li, p2);
OneList* pp=p1O;
OneList* left = p1O->prev;
OneList* right = p2O->next;
for (; pp != p2O; )
{
pp = pp->next;
free(pp->prev);
li->_current--;
}
free(pp);//释放p2O
li->_current--;
left->next = right;
right->prev = left;
if (p1O == li->_date)
{
li->_date = right;
}
}
void List_erase_int(list* li, const int left, const int right)
{
OneList* pleft=NULL ;
OneList* pright=NULL;
OneList* p=li->_date;
OneList* pp = p;
for (size_t i = 0; i <= right; i++)
{
p = p->next;
if (i >= left && i <= right)
{
if (i == left)
{
pleft = p->prev->prev;
}
if(i==right)
{
pright = p;
}
if (p == li->_date)
{
free(pp);
}
else
{
pp = p;
free(p->prev);
}
li->_current--;
}
}
pleft->next = pright;
pright->prev = pleft;
if (li->_current==0)
{
li->_date = NULL;
}
else if (left== 0)
{
li->_date = pright;
}
}
void List_clear(list* li)
{
OneList* p = li->_date;
OneList* pnext = p->next;
for (size_t i = 0; i < li->_current; i++)
{
pnext = p->next;
free(p);
p = pnext;
}
li->_current = 0;
li->_date = NULL;
}
void* List_at(const list* li, int n)
{
if (n >= 0 && n < li->_current)
{
OneList* p = li->_date;
if (n == 0)
{
return p->data;
}
for (size_t j = 0; j < n; j++)
{
p = p->next;
}
return p->data;
}
return NULL;
}
void* List_front(list* li)
{
return li->_date->data;
}
void* List_back(list* li)
{
return li->_date->prev->data;
}
void* List_find(const list* li, const void* val)
{
return find(li, val)->data;
}
bool List_empty(const list* li)
{
return !li->_current;
}
size_t List_size(const list* li)
{
return li->_current;
}
void List_sort(list* li, bool(*Sort)(void* x, void* y))
{
char* p1;//指向第一个元素
char* p2;
for (size_t n1 = 0; n1 <li->size(li)-1; n1++)
{
p1 = li->at(li, n1);
for (size_t n2 = n1+1; n2 <li->size(li); n2++)
{
p2 = li->at(li, n2);
if (!Sort(p1, p2))//排序比较函数,返回布尔值
{
swap(p1, p2, li->_type);//交换函数
}
}
}
}
void List_swap(list* li1, list* li2)
{
swap(&li1->_date,&li2->_date, sizeof(OneList*));
swap(&li1->_current, &li2->_current, sizeof(size_t));
}
void ListInitial(list* li, int n)
{
li->push_front = List_push_front;
li->push_back = List_push_back;
li->insert_front = List_insert_front;
li->insert = List_insert;
li->at = List_at;
li->pop_front = List_pop_front;
li->pop_back = List_pop_back;
li->erase_p = List_erase_p;
li->erase_int = List_erase_int;
li->clear = List_clear;
li->at = List_at;
li->front = List_front;
li->back = List_back;
li->find = List_find;
li->empty = List_empty;
li->size = List_size;
li->sort = List_sort;
li->swap = List_swap;
li->_type = n;
li->_current = 0;
li->_date = NULL;
}
test.c(测试代码)
#include"list.h"
bool mysort(void* x, void* y)//自定义的排序回调函数
{
return *(int*)x < *(int*)y;
}
test01()
{
list li;
ListInitial(&li, sizeof(int));
int num;
num = 1;
li.push_front(&li, &num);
num = 2;
li.push_front(&li, &num);
num = 3;
li.push_front(&li, &num);
num = 10;
li.push_back(&li, &num);
num = 30;
li.push_back(&li, &num);
num = 2;
int x = 100;
li.insert_front(&li, &num,&x,4);
int arr[5] = { 123,12,1,4,9 };
num = 100;
li.insert(&li, &num,&arr[0], &arr[4]);
printf("元素遍历\n");
for (size_t i = 0; i < li.size(&li); i++)
{
printf("%d\n", *(int*)li.at(&li, i));
}
printf("头元素为:%d\n", *(int*)li.front(&li));
printf("尾元素为:%d\n", *(int*)li.back(&li));
int findn = 10;
printf("找到的元素为:%d\n", *(int*)li.find(&li,&findn));
li.sort(&li, mysort);
printf("排序后元素后遍历\n");
for (size_t i = 0; i < li.size(&li); i++)
{
printf("%d\n", *(int*)li.at(&li, i));
}
/*li.pop_back(&li);
li.pop_back(&li);
li.pop_front(&li);
li.pop_front(&li);*/
int delen1 = 2;
int delen2 = 3;
//li.erase_p(&li, &delen1,& delen1);
li.erase_int(&li,1, 8);
printf("删除元素后遍历\n");
for (size_t i = 0; i < li.size(&li); i++)
{
printf("%d\n", *(int*)li.at(&li, i));
}
li.clear(&li);
}
test02()//交换函数测试
{
list li1;
ListInitial(&li1, sizeof(int));
int num;
for (size_t i = 0; i < 10; i++)
{
num = i;
li1.push_front(&li1, &num);
}
printf("li1元素遍历\n");
for (size_t i = 0; i < li1.size(&li1); i++)
{
printf("%d\n", *(int*)li1.at(&li1, i));
}
list li2;
ListInitial(&li2, sizeof(int));
for (size_t i = 0; i < 20; i++)
{
num = 20-i;
li1.push_front(&li2, &num);
}
printf("li2元素遍历\n");
for (size_t i = 0; i < li2.size(&li2); i++)
{
printf("%d\n", *(int*)li2.at(&li2, i));
}
li1.swap(&li1, &li2);
printf("交换后li1元素遍历\n");
for (size_t i = 0; i < li1.size(&li1); i++)
{
printf("%d\n", *(int*)li1.at(&li1, i));
}
printf("交换后li2元素遍历\n");
for (size_t i = 0; i < li2.size(&li2); i++)
{
printf("%d\n", *(int*)li2.at(&li2, i));
}
li1.clear(&li1);
li2.clear(&li2);
}
int main()
{
test01();
return 0;
}