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;}


原创粉丝点击