数据结构 链表_双向链表的实现与分析

Posted DreamGo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 链表_双向链表的实现与分析相关的知识,希望对你有一定的参考价值。

双向链表的实现与分析

双向链表的组成 :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;  
    }  

 

以上是关于数据结构 链表_双向链表的实现与分析的主要内容,如果未能解决你的问题,请参考以下文章

双向链表的实现(双向链表与单向链表的简单区别联系和实现)

双向链表的实现(双向链表与单向链表的简单区别联系和实现)

数据结构与算法

链表的java实现(单向双向链表,单向链表的反转)

链表的java实现(单向双向链表,单向链表的反转)

算法_链表篇