2. linux C -- 通用双向链表
来源:互联网 发布:js将字符串向下取整 编辑:程序博客网 时间:2024/05/19 17:05
1. 头文件 list.h 代码(定义链表结构体及一些需要实现的函数)
#ifndef _LIST_H_#define _LIST_H_#include <stdio.h>#include <stdlib.h>#include <string.h>#define ERRP(con, func, ret) do{\if (con)\{\perror(func);\ret;\}\}while(0)typedef struct node{int size; //数据的类型void *data;//数据域struct node *prev;struct node *next;}NODE;typedef void (list_op_t)(void *);typedef int (list_cmp_t)(void *, void *);NODE *create_list(int size);//创建链表int add_node_head(NODE *head, void *data);// 头部插入int add_node_tail(NODE *head, void *data);// 尾部插入void travel_list(NODE *head, list_op_t *op);// 遍历int list_len(NODE *head);void *list_find(NODE *head, void *key, list_cmp_t *cmp);//按关键字查找void *list_index(NODE *head, int index);//按位置查找NODE *list_alfind(NODE *head, void *key, list_cmp_t *cmp);//查找全部void list_del(NODE *head, void *key, list_cmp_t *cmp);// 按关键字删除void list_indexdel(NODE *head, int index);// 按位置删除void list_aldel(NODE *head, void *key, list_cmp_t *cmp);// 按关键字删除所有void list_sort(NODE *head, list_cmp_t *cmp);//排序void list_invert(NODE *head, list_op_t *op);// 倒置void destroy_list(NODE *head);// 销毁#endif
2. 创建链表
参数: 链表数据域的大小
返回值:链表头
NODE *create_list(int size){NODE *head = NULL;head = (NODE *)malloc(sizeof(NODE));ERRP(NULL == head, "malloc", goto ERR1);head->data = NULL;head->size = size;head->prev = head;head->next = head;return head;ERR1:return NULL;}3. 链表头部插入数据
参数: 链表头, 插入的数据指针
返回值: 成功返回0, 失败返回-1
int add_node_head(NODE *head, void *data){ NODE *newNode = NULL; newNode = (NODE *)malloc(sizeof(NODE)); ERRP(NULL == newNode, "add_node_head", goto ERR1); newNode->data = (void *)malloc(head->size); ERRP(NULL == newNode->data, "add_node_head", goto ERR2); memcpy(newNode->data, data, head->size); newNode->next = head->next; head->next->prev = newNode; newNode->prev = head; head->next = newNode;return 0;ERR2: free(newNode);ERR1:return -1;}
4. 链表头部插入数据
参数: 链表头
插入的数据指针
返回值: 成功返回0, 失败返回-1
int add_node_tail(NODE *head, void *data){ NODE *newNode = NULL; newNode = (NODE *)malloc(sizeof(NODE)); ERRP(NULL == newNode, "add_node_tail", goto ERR1); newNode->data = (void *)malloc(head->size); ERRP(NULL == newNode, "add_node_tail", goto ERR2); memcpy(newNode->data, data, head->size); newNode->prev = head->prev; head->prev->next = newNode; newNode->next = head; head->prev = newNode;return 0;ERR2: free(newNode);ERR1:return 0;}5. 遍历函数
参数:链表头
处理遍历到的链表值的函数指针
返回值:无
void travel_list(NODE *head, list_op_t *op){NODE *tail = NULL;tail = head;while (tail->next != head){op(tail->next->data);tail = tail->next;}return;}
6. 得到链表长度
参数: 链表头
返回值: 链表长度
int get_list_len(NODE *head){int count = 0;NODE *tail = NULL;tail = head;while (tail->next != head){count++;tail = tail->next;}return count;}
7. 按关键字查询
参数: 链表头
关键字
匹配方式
返回值:查询到的链表节点的值域(若有多个匹配只会返回第一个,如找不到则返回NULL)
void *list_find(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){return tail->next->data;}tail = tail->next;}return NULL;}
8. 按索引查找
参数: 链表头
索引值
返回值:查询到的链表节点的值域(如找不到则返回NULL)
void *list_index(NODE *head, int index){NODE *tail = NULL;int count = 1;ERRP(count < 1 || count > list_len(head), "index", goto ERR1);tail = head;while (tail->next != head){if (count == index){return tail->next->data;}count++;tail = tail->next;}ERR1:return NULL;}9. 查找全部符合关键字的链表内容
参数: 链表头
关键字
匹配方式
返回值:一个新的链表
NODE *list_alfind(NODE *head, void *key, list_cmp_t *cmp){NODE *alfind = NULL;NODE *tail = NULL;alfind = create_list(head->size);ERRP(NULL == alfind, "create_list", goto ERR1);tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){add_node_tail(alfind, tail->next->data);}tail = tail->next;}/*if (alfind == alfind->prev){printf("no find");}*/return alfind;ERR1:return NULL;}
10. 查找全部符合关键字的链表内容
参数: 链表头
关键字
匹配方式
返回值:无(若有多个则只会删除第一个节点)
void list_del(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;NODE *tmp = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){tmp = tail->next->next;free(tail->next->data);free(tail->next);tail->next = tmp;tmp->prev = tail;return ;}tail = tail->next;}return;}
11. 查找全部符合关键字的链表内容
参数: 链表头
关键字
匹配方式
返回值:无(删除所有匹配的节点)
void list_aldel(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;NODE *tmp = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){tmp = tail->next->next;free(tail->next);tail->next = tmp;tmp->prev = tail;continue;}tail = tail->next;}return;}
11. 查找全部符合关键字的链表内容
参数: 链表头
关键字
匹配方式
返回值:无(删除所有匹配的节点)
void list_aldel(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;NODE *tmp = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){tmp = tail->next->next;free(tail->next);tail->next = tmp;tmp->prev = tail;continue;}tail = tail->next;}return;}
12. 排序
参数: 链表头
排序方式指针
返回值: 无
void list_sort(NODE *head, list_cmp_t *cmp){NODE *tail = NULL;NODE *tnext = NULL;void *tmp = NULL;tmp = (void *)malloc(head->size);ERRP(NULL == tmp, "malloc", goto ERR1);for (tail = head; tail->next != head; tail = tail->next){for (tnext = tail->next; tnext->next != head; tnext = tnext->next){if (0 > cmp(tail->next->data, tnext->next->data)){memcpy(tmp , tail->next->data, head->size);memcpy(tail->next->data, tnext->next->data, head->size);memcpy(tnext->next->data, tmp, head->size);}}}return;ERR1:return;}13. 倒置
参数: 链表头
返回值:无
void list_invert(NODE *head){NODE *tail = NULL;tail = head;while (tail->prev != head){op(tail->prev->data);tail = tail->prev;}return;}14. 销毁
参数:链表头
返回值: 无
void destroy_list(NODE *head){NODE *tail = NULL;NODE *tnext = NULL;tail = head->next;while (tail != head){tnext = tail->next;free(tail->data);free(tail);tail = tnext;}free(head);}
15. list.c
#include "list.h"NODE *create_list(int size){NODE *head = NULL;head = (NODE *)malloc(sizeof(NODE));ERRP(NULL == head, "malloc", goto ERR1);head->data = NULL;head->size = size;head->prev = head;head->next = head;return head;ERR1:return NULL;}int add_node_head(NODE *head, void *data){ NODE *newNode = NULL; newNode = (NODE *)malloc(sizeof(NODE)); ERRP(NULL == newNode, "add_node_head", goto ERR1); newNode->data = (void *)malloc(head->size); ERRP(NULL == newNode->data, "add_node_head", goto ERR2); memcpy(newNode->data, data, head->size); newNode->next = head->next; head->next->prev = newNode; newNode->prev = head; head->next = newNode;return 0;ERR2: free(newNode);ERR1:return -1;}int add_node_tail(NODE *head, void *data){ NODE *newNode = NULL; newNode = (NODE *)malloc(sizeof(NODE)); ERRP(NULL == newNode, "add_node_tail", goto ERR1); newNode->data = (void *)malloc(head->size); ERRP(NULL == newNode, "add_node_tail", goto ERR2); memcpy(newNode->data, data, head->size); newNode->prev = head->prev; head->prev->next = newNode; newNode->next = head; head->prev = newNode;return 0;ERR2: free(newNode);ERR1:return 0;}void travel_list(NODE *head, list_op_t *op){NODE *tail = NULL;tail = head;while (tail->next != head){op(tail->next->data);tail = tail->next;}return;}void *list_find(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){return tail->next->data;}tail = tail->next;}return NULL;}int list_len(NODE *head){int count = 0;NODE *tail = NULL;tail = head;while (tail->next != head){count++;tail = tail->next;}return count;}void *list_index(NODE *head, int index){NODE *tail = NULL;int count = 1;ERRP(count < 1 || count > list_len(head), "index", goto ERR1);tail = head;while (tail->next != head){if (count == index){return tail->next->data;}count++;tail = tail->next;}ERR1:return NULL;}NODE *list_alfind(NODE *head, void *key, list_cmp_t *cmp){NODE *alfind = NULL;NODE *tail = NULL;alfind = create_list(head->size);ERRP(NULL == alfind, "create_list", goto ERR1);tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){add_node_tail(alfind, tail->next->data);}tail = tail->next;}/*if (alfind == alfind->prev){printf("no find");}*/return alfind;ERR1:return NULL;}void list_del(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;NODE *tmp = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){tmp = tail->next->next;free(tail->next->data);free(tail->next);tail->next = tmp;tmp->prev = tail;return ;}tail = tail->next;}return;}void list_indexdel(NODE *head, int index){int count = 1;NODE *tail = NULL;NODE *tmp = NULL;ERRP(index < 1 || index > list_len(head), "index", goto ERR1);tail = head;while (tail->next != head){if (count == index){tmp = tail->next->next;free(tail->next);tail->next = tmp;tmp->prev = tail;return;}count++;tail = tail->next;}return;ERR1:return;}void list_aldel(NODE *head, void *key, list_cmp_t *cmp){NODE *tail = NULL;NODE *tmp = NULL;tail = head;while (tail->next != head){if (0 == cmp(tail->next->data, key)){tmp = tail->next->next;free(tail->next);tail->next = tmp;tmp->prev = tail;continue;}tail = tail->next;}return;}void list_sort(NODE *head, list_cmp_t *cmp){NODE *tail = NULL;NODE *tnext = NULL;void *tmp = NULL;tmp = (void *)malloc(head->size);ERRP(NULL == tmp, "malloc", goto ERR1);for (tail = head; tail->next != head; tail = tail->next){for (tnext = tail->next; tnext->next != head; tnext = tnext->next){if (0 > cmp(tail->next->data, tnext->next->data)){memcpy(tmp , tail->next->data, head->size);memcpy(tail->next->data, tnext->next->data, head->size);memcpy(tnext->next->data, tmp, head->size);}}}return;ERR1:return;}void list_travel_invert(NODE *head, list_op_t *op){NODE *tail = NULL;tail = head;while (tail->prev != head){op(tail->prev->data);tail = tail->prev;}return;}void destroy_list(NODE *head){NODE *tail = NULL;NODE *tnext = NULL;tail = head->next;while (tail != head){tnext = tail->next;free(tail->data);free(tail);tail = tnext;}free(head);}void list_store(NODE *head, char *path){FILE *fp = NULL;int ret;NODE *tail = NULL;int len;fp = fopen(path, "w");ERRP(NULL == fp, "fopen", goto ERR1);len = list_len(head);ret = fwrite(&head->size,sizeof(head->size), 1, fp);ERRP(1 != ret, "fwrite size", goto ERR2);ret = fwrite(&len, sizeof(len), 1, fp);ERRP(1 != ret, "fwrite len", goto ERR2);tail = head;while (tail->next != head){ret = fwrite(tail->next->data, head->size, 1, fp);ERRP(1 != ret, "fwrite data", goto ERR2);tail = tail->next;}fclose(fp);return ;ERR2:fclose(fp);ERR1:return;}void list_load(NODE *load, char *path){int i;int size, len;int ret;FILE *fp = NULL;void *data = NULL;fp = fopen(path, "r");ERRP(NULL == fp, "fopen", goto ERR1);ret = fread(&size, sizeof(size), 1, fp);ERRP(1 != ret, "fread size", goto ERR2);ret = fread(&len, sizeof(len), 1, fp);ERRP(1 != ret, "fread len", goto ERR2);data = (void *)malloc(size);ERRP(NULL == data, "malloc data", goto ERR2);for (i = 0; i < len; i++){ret = fread(data, size, 1, fp);ERRP(1 != ret, "fread data", goto ERR3);add_node_tail(load, data);}fclose(fp);return;ERR3:free(data);ERR2:fclose(fp);ERR1:return;}
阅读全文
0 0
- 2. linux C -- 通用双向链表
- C实现通用数据结构--双向链表
- 通用双向链表
- 通用双向链表的C语言实现
- 双向循环链表 C语言通用编程的思考
- C语言通用双向链表的实现
- C语言通用双向循环链表操作函数集
- C语言中如何使用通用双向链表
- 实现通用的双向链表(c语言实现)
- linux内核部件--通用双向链表list
- linux内核部件--通用双向链表list
- 通用的双向链表
- 通用的双向链表(值得收藏)
- 双向链表的通用模板
- 关于通用双向链表的使用
- 数据结构通用双向循环链表实现
- 简单通用的双向链表
- 一个通用的双向链表
- GVP 特辑:6款 Java WEB应用开发工具
- Python3+BeautifulSoup报错UnicodeEncodeError: 'charmap' codec can't encode characters in position
- C语言 两个整数合并成一个整数
- 重启Oracle服务
- IOS6和IOS7的屏幕适配问题
- 2. linux C -- 通用双向链表
- 嚼得菜根做得大事·《菜根谭》·二
- C++顺序表(十四)
- Eclipse开发Webservice
- ECS 还是轻量应用服务器,看完评测你就知道了?
- jeecg 文本编辑器
- 测试项目招标拿不下?一定是因为你没有这个
- bootstrap前端框架的简单使用
- bzoj2438 [中山市选2011]杀人游戏(tarjan缩点)