链表-C语言实现

来源:互联网 发布:移动电玩城作弊软件 编辑:程序博客网 时间:2024/04/27 02:42

单向链表

list.h

//list.h#ifndef LIST_H#define LIST_H#include <stdlib.h>typedef struct ListElmt_{    void *data;    struct ListElmt_ *next;} ListElmt;typedef struct List_{    int size;    int (*match)(const void *key1, const void *key2);    void (*destroy)(void *data);    ListElmt *head;    ListElmt *tail;} List;/* public interface */void list_init(List *list, void (*destroy)(void *data));void list_destroy(List *list);int list_ins_next(List *list, ListElmt *element, const void *data);int list_rem_next(List *list, ListElmt *element, void **data);#define list_size(list) ((list)->size)#define list_head(list) ((list)->head)#define list_tail(list) ((list)->tail)#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)#define list_is_tail(element) ((element)->next == NULL ? 1 : 0)#define list_data(element) ((element)->data)#define list_next(element) ((element)->next)#endif

list.c

//list.c#include <stdlib.h>#include <string.h>#include "list.h"/** * 初始化链表 * @param list 要初始化的链表 * @param destory 如果节点中的数据需要destroy,则提供destroy函数,该函数 * 在list_destroy中被调用,用于销毁节点中的数据。如果节点中的数据不需要销毁, * 则该参数传NULL。 */void list_init(List *list, void (*destroy)(void *data)){    list->size = 0;    list->destroy = destroy;    list->head = NULL;    list->tail = NULL;}/** * 销毁链表 * @param list 要销毁的链表 */void list_destroy(List *list){    void *data;    while (list_size(list) > 0) {        if (list_rem_next(list, NULL, (void **)&data) == 0 && list->destroy != NULL) {            list->destroy(data);        }    }    memset(list, 0, sizeof(List));}/** * 将元素data插入到链表list的element节点后面。如果element为NULL, * 则新的节点插入到链表的开始。 * @param  list    要操作的链表 * @param  element 指定的节点 * @param  data    要插入的数据 * @return         成功返回0;失败返回-1; */int list_ins_next(List *list, ListElmt *element, const void *data){    ListElmt *new_element;    if ((new_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL)        return -1;    new_element->data = (void*)data;    if (element == NULL) {        /* 当链表中没有节点时 */        if (list_size(list) == 0)            list->tail = new_element;        new_element->next = list->head;        list->head = new_element;    } else {        /* 当指定的元素为最后一个节点时 */        if (element->next == NULL)            list->tail = new_element;        new_element->next = element->next;        element->next = new_element;    }    list->size++;    return 0;}/** * 将节点element从链表list中删除 * @param  list    要操作的链表 * @param  element 指定的节点 * @param  data    用于保存被删除的节点中的数据 * @return         成功返回0;失败返回-1; */int list_rem_next(List *list, ListElmt *element, void **data){    ListElmt *old_element;    if (list_size(list) == 0)        return -1;    if (element == NULL) {        *data = list->head->data;        old_element = list->head;        list->head = list->head->next;        if (list_size(list) == 1)            list->tail = NULL;    } else {        if (element->next == NULL)            return -1;        *data = element->next->data;        old_element = element->next;        element->next = element->next->next;        /* 如果移除的是尾节点,调整尾节点 */        if (element->next == NULL)            list->tail = element;    }    free(old_element);    list->size--;    return 0;}

双向链表

dlist.h

/** * 双向链表,dlist.h */#ifndef DLIST_H#define DLIST_H#include <stdlib.h>typedef struct DListElmt_{    void *data;    struct DListElmt_ *prev;    struct DListElmt_ *next;} DListElmt;typedef struct DList_{    int size;    int (*match)(const void *key1, const void *key2);    void (*destroy)(void *data);    DListElmt *head;    DListElmt *tail;} DList;/* public interface */void dlist_init(DList *list, void (*destroy)(void *data));void dlist_destroy(DList *list);int dlist_ins_next(DList *list, DListElmt *element, const void *data);int dlist_ins_prev(DList *list, DListElmt *element, const void *data);int dlist_remove(DList *list, DListElmt *element, void **data);#define dlist_size(list) ((list)->size)#define dlist_head(list) ((list)->head)#define dlist_tail(list) ((list)->tail)#define dlist_is_head(list, element) ((element) == (list)->head ? 1 : 0)#define dlist_is_tail(element) ((element)->next == NULL ? 1 : 0)#define dlist_data(element) ((element)->data)#define dlist_next(element) ((element)->next)#define dlist_prev(element) ((element)->prev)#endif

dlist.c

/** * 双向链表,dlist.c */#include <stdlib.h>#include <string.h>#include "dlist.h"/** * 初始化链表 * @param list 要初始化的链表 * @param destory 指定一个销毁数据的函数,该函数会在dlist_destroy中调用。 */void dlist_init(DList *list, void (*destroy)(void *data)){    list->size = 0;    list->destroy = destroy;    list->head = NULL;    list->tail = NULL;}/** * 销毁链表 * @param list 要销毁的链表 */void dlist_destroy(DList *list){    void *data;    while (dlist_size(list) > 0) {        if (dlist_remove(list, dlist_tail(list), (void **)&data) == 0             && list->destroy != NULL) {            list->destroy(data);        }    }    memset(list, 0, sizeof(DList));}/** * 将元素插入由list指定的双向链表中element元素之后。如果element为NULL。 * 则将元素插入到链表的开始位置。新的元素包含一个指向data的指针,因此只要 * 该元素仍在链表中,data所引用的内存空间就应该保持合法。由调用者负责管理 * data所引用的存储空间。 * @param  list    要操作的链表 * @param  element 指定的节点 * @param  data    要插入的元素 * @return         成功返回0,失败返回-1 */int dlist_ins_next(DList *list, DListElmt *element, const void *data){    DListElmt *new_element;    if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL)        return -1;    new_element->data = (void *)data;    if (element == NULL) {        if (dlist_size(list) == 0) {            new_element->next = NULL;            new_element->prev = NULL;            list->head = new_element;            list->tail = new_element;        } else {            new_element->next = list->head;            new_element->prev = NULL;            list->head->prev = new_element;            list->head = new_element;        }    } else {        new_element->next = element->next;        new_element->prev = element;        if (element->next == NULL)            list->tail = new_element;        else            element->next->prev = new_element;        element->next = new_element;    }    list->size++;    return 0;}/** * 将元素插入由list指定的双向链表中element元素之前。如果element为NULL。 * 则将元素插入到链表的开始位置。新的元素包含一个指向data的指针,因此只要 * 该元素仍在链表中,data所引用的内存空间就应该保持合法。由调用者负责管理 * data所引用的存储空间。 * @param  list    要操作的链表 * @param  element 指定的节点 * @param  data    要插入的元素 * @return         成功返回0,失败返回-1 */int dlist_ins_prev(DList *list, DListElmt *element, const void *data){    DListElmt *new_element;    if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL)        return -1;    if (element == NULL) {        if (dlist_size(list) == 0) {            list->head = new_element;            list->tail = new_element;            new_element->next = NULL;            new_element->prev = NULL;        } else {            new_element->next = list->head;            new_element->prev = NULL;            list->head->prev = new_element;            list->head = new_element;        }    } else {        new_element->next = element;        new_element->prev = element->prev;        if (element->prev == NULL)            list->head = new_element;        else            element->prev->next = new_element;        element->prev = new_element;    }    return 0;}/** * 将元素element从链表中移除 * @param  list    要操作的链表 * @param  element 要从链表中移除的节点 * @param  data    移除的节点中的数据 * @return         成功返回0;失败返回-1。 */int dlist_remove(DList *list, DListElmt *element, void **data){    if (element == NULL || dlist_size(list) == 0)        return -1;    *data = element->data;    if (element == list->head) {        list->head = element->next;        if (list->head == NULL)            list->tail = NULL;        else            element->next->prev = NULL;    } else {        // 将前一个节点的next指向当前节点的下一个节点        element->prev->next = element->next;        // 如果这个节点是最后一个节点,删除后,将尾指针指向当前节点的前一个节点;        // 如果不是最后一个节点,则将后一个节点的prev指向当前节点的前一个节点。        if (element->next == NULL)            list->tail = element->prev;        else            element->next->prev = element->prev;    }    free(element);    list->size--;    return 0;}

单向循环链表

clist.h

/** * 单向循环链表,clist.h */#ifndef CLIST_H#define CLIST_H#include <stdlib.h>typedef struct CListElmt_{    void *data;    struct CListElmt_ *next;} CListElmt;typedef struct CList_{    int size;    int (*match)(const void *key1, const void *key2);    void (*destroy)(void *data);    CListElmt *head;} CList;/* public interface */void clist_init(CList *list, void (*destroy)(void *data));void clist_destroy(CList *list);int clist_ins_next(CList *list, CListElmt *element, const void *data);int clist_rem_next(CList *list, CListElmt *element, void **data);#define clist_size(list) ((list)->size)#define clist_head(list) ((list)->head)#define clist_data(element) ((element)->data)#define clist_next(element) ((element)->next)#endif

clist.c

/** * 单向循环链表,clist.c */#include <stdlib.h>#include <string.h>#include "clist.h"void clist_init(CList *list, void (*destroy)(void *data)){    list->size = 0;    list->destroy = destroy;    list->head = NULL;}void clist_destroy(CList *list){    void *data;    while (clist_size(list) > 0) {        if (clist_rem_next(list, list->head, (void **)&data) == 0            && list->destroy != NULL) {            list->destroy(data);        }    }    memset(list, 0, sizeof(CList));}/** * 插入元素到链表list的节点element后面。 * @param  list    链表 * @param  element 节点 * @param  data    数据 * @return         成功返回0,失败-1 */int clist_ins_next(CList *list, CListElmt *element, const void *data){    CListElmt *new_element;    if ((new_element = (CListElmt *)malloc(sizeof(CListElmt))) == NULL)        return -1;    new_element->data = (void *)data;    if (clist_size(list) == 0) {        new_element->next = new_element;        list->head = new_element;    } else {        new_element->next = element->next;        element->next = new_element;    }    list->size++;    return 0;}/** * 从链表list中删除element节点。 * @param  list    链表 * @param  element 节点 * @param  data    被删除节点中的数据 * @return         成功返回0,失败返回-1 */int clist_rem_next(CList *list, CListElmt *element, void **data){    CListElmt *old_element;    if (clist_size(list) == 0)        return -1;    *data = element->next->data;    if (element->next == element) {        old_element = element->next;        list->head = NULL;    } else {        old_element = element->next;        element->next = element->next->next;        if (old_element == clist_head(list))            list->head = old_element->next;    }    free(old_element);    list->size--;    return 0;}
0 0
原创粉丝点击