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

双向链表的实现与分析

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值