1 Star 0 Fork 4

wangbo20 / C-List

forked from saury / C-List 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
list.c 5.91 KB
一键复制 编辑 原始数据 按行查看 历史
saury 提交于 2022-06-06 11:23 . 增加用户自定义内存释放函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "list.h"
typedef struct _LINE_
{
struct _LINE_* next;
struct _LINE_* pre;
void* data;
uint32_t datalen;
}LINE_t;
typedef struct _BODY_
{
LINE_t* _head;
LINE_t* _tail;
int _num;
int _max_num;
int _max_len;
void (*_data_free)(void*);
}BODY_t;
static void _free_line_data(BODY_t* body, void* data)
{
if(NULL == data)
return;
if(NULL != body->_data_free)
{
body->_data_free(data);
return;
}
free(data);
}
static void _destruct(LIST_t** _list)
{
if(NULL == _list) return;
LIST_t* list = *_list;
BODY_t* body = (BODY_t*)list->_body;
list->clear(list);
LINE_t* line = body->_head;
if(NULL != list->_body)
{
free(list->_body);
list->_body = NULL;
}
free(list);
list = NULL;
}
static void _clear(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
LINE_t* line = body->_head;
while(line != NULL)
{
LINE_t* p = line->next;
_free_line_data(body, line->data);
free(line);
line = p;
}
body->_head = NULL;
body->_tail = NULL;
}
static int _push_back(LIST_t* list, void* data, int len)
{
BODY_t* body = (BODY_t*) list->_body;
if(body->_num >= body->_max_num || len > body->_max_len)
return -1;
LINE_t* line = (LINE_t*) malloc(sizeof(LINE_t));
if(NULL == line)
return -2;
memset(line, 0, sizeof(LINE_t));
line->data = malloc(len);
if(NULL == line->data)
{
free(line);
return -2;
}
memset(line->data, 0, len);
memcpy(line->data, data, len);
line->datalen = len;
body->_num ++;
if(NULL == body->_head) // 这里认为初始化, 头尾都指向同个结构
{
body->_head = line;
body->_tail = line;
return 0;
}
line->pre = body->_tail;
body->_tail->next = line;
body->_tail = line;
return 0;
}
static int _push_front(LIST_t* list, void* data, int len)
{
BODY_t* body = (BODY_t*) list->_body;
if(body->_num + 1 >= body->_max_num || len > body->_max_len)
return -1;
LINE_t* line = (LINE_t*) malloc(sizeof(LINE_t));
if(NULL == line)
return -2;
memset(line, 0, sizeof(LINE_t));
line->data = malloc(len);
if(NULL == line->data)
{
free(line);
return -2;
}
memset(line->data, 0, len);
memcpy(line->data, data, len);
line->datalen = len;
body->_num ++;
if(NULL == body->_head) // 这里认为初始化, 头尾都指向同个结构
{
body->_head = line;
body->_tail = line;
return 0;
}
line->next = body->_head;
body->_head->pre = line;
body->_head = line;
return 0;
}
static void* _front(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
if(NULL == body)
return NULL;
return body->_head->data;
}
static void* _back(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
if(NULL == body)
return NULL;
return body->_tail->data;
}
// 轮询删除, 正常不建议使用 O(n), data 是链表中的指针
static void _erase(LIST_t* list, void* data)
{
BODY_t* body = (BODY_t*)list->_body;
LINE_t* line = body->_head;
while(line)
{
if(line->data == data)
{
LINE_t* p = line;
if(NULL != p->pre)
p->pre->next = p->next;
if(NULL != p->next)
p->next->pre = p->pre;
if(body->_head == p)
{
body->_head = p->next;
}
if(body->_tail == p)
{
body->_tail = p->pre;
}
body->_num--;
_free_line_data(body, line->data);
free(line);
break;
}
line = line->next;
}
}
static void _pop_front(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
LINE_t* line = body->_head;
if(NULL == line)
return;
body->_head = line->next;
if(NULL != body->_head)
body->_head->pre = NULL;
if(line == body->_tail)
body->_tail = NULL;
_free_line_data(body, line->data);
free(line);
body->_num--;
}
static void _pop_back(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
LINE_t* line = body->_tail;
if(NULL == line)
return;
body->_tail = line->pre;
if(NULL != body->_tail)
body->_tail->next = NULL;
if(line == body->_head)
body->_head = NULL;
_free_line_data(body, line->data);
free(line);
body->_num--;
}
static bool _empty(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
return (body->_tail == NULL);
}
static int _size(LIST_t* list)
{
BODY_t* body = (BODY_t*)list->_body;
return body->_num;
}
static int _construct(LIST_t* list, int max_num, int max_len, void (*data_free)(void*)) // 调用前要确定 list 已经分配内存
{
list->_body = malloc(sizeof(BODY_t));
if(NULL == list->_body)
return -1;
memset(list->_body, 0, sizeof(BODY_t));
BODY_t* body = (BODY_t*)list->_body;
body->_max_num = max_num;
body->_max_len = max_len;
body->_data_free = data_free;
list->push_back = _push_back;
list->push_front = _push_front;
list->front = _front;
list->back = _back;
list->pop_front = _pop_front;
list->pop_back = _pop_back;
list->erase = _erase;
list->empty = _empty;
list->size = _size;
list->clear = _clear;
list->destruct = _destruct;
return 0;
}
LIST_t* create_list(int max_num, int max_len, void (*data_free)(void*))
{
LIST_t* list = (LIST_t*)malloc(sizeof(LIST_t));
if(NULL == list)
return NULL;
memset(list, 0, sizeof(LIST_t));
if( _construct(list, max_num, max_len, data_free)!= 0)
{
free(list);
return NULL;
}
return list;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wangbo20/c-list.git
git@gitee.com:wangbo20/c-list.git
wangbo20
c-list
C-List
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891