「算法精解_C语言描述」 链表_双向链表的实现与分析

来源:互联网 发布:易语言写软件 编辑:程序博客网 时间:2024/06/01 07:26

双向链表的实现与分析

*关于双向链表的接口定义,请参阅前篇文章:双向链表的接口定义

双向链表的组成 :1、数据成员;2、指向下一个元素的next指针;3、指向前一个元素的prev指针。

数据结构DListElmt:代表双向链表中的单个元素(节点)。

数据结构DList:代表双向链表数据结构,该结构的成员同前面介绍的单链表相似。

示例1:双向链表抽象数据类型的头文件

/*dlist.h*/#ifndef  DLIST_H#define  DLIST_H/*定义双向链表中的元素*/typedef struct DListLemt_{    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;/*公共接口*/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(element)((element)->prev == NULL ? 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


示例2: 双向链表抽象数据类型的实现

/*dlist.c*/#include <stdio.h>#include <string.h>#include "dlist.h"/*dlist_init    初始化双向链表*/void dlist_init(DList *list,void(*destroy)(void *data)){    list->size = 0;    list->destroy = destroy;    list->head = NULL;    list->tail = NULL;    return ;}/*dlist_destroy  销毁双向链表*/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));    return;}/*dlist_ins_next  将元素插入指定元素之后*/int dlist_ins_next(DList *list,DListElmt *element,const void *data){    DListElmt *new_element;    /*除非链表为空,否则不允许使用null元素。*/    if(element == NULL && dlist_size(list) != 0)        return -1;    /*为元素分配空间*/    if((new_element=(DListElmt*)malloc(sizeof(DListElmt)))==NULL)        return -1;    /*将新元素插入链表*/    new_element->data = (void*)data;    if(dlist_size(list)==0)    {        /*链表为空时*/        list->head = new_element;        list->head->prev = NULL;        list->head->next = NULL;        list->tail = 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;}/*dlist_ins_prev*/int dlist_ins_prev(DList *list,DListElmt *element,const void *data){    DListElmt *new_element;        /*除非链表为空,否则不允许element为null*/    if(element == NULL && dlist_size(list)!=0)        return -1;        /*为新元素分配存储*/    if((new_element=(DlistElmt *)malloc(sizeof(DListElmt))==NULL)        return -1;        /*insert the new element into the list*/    new_element->data=(void *data);    if(dlist_size(list)==0)    {        /*链表为空*/        list->head = new_element;        list->head->prev = NULL;        list->tail->tail = NULL;        list->tail = 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;    }    /*改变链表中结点数量*/    list->size++;    return 0;} /*dlist_remove*/int dlist_remove(Dlist *list,DList_Elmt *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    {        /*从链表其他位置移除元素操作*/        element->prev->next = element->next;                if(element->next == NULL)            list->tail = element->prev;        else            element->next->prev = element->prev;    }        /*释放空间*/    free(element);    /*改变链表中结点数量*/    list->size--;    return 0;}


阅读全文
0 0
原创粉丝点击