双链表的实现

来源:互联网 发布:网络嘿嘿嘿是什么意思 编辑:程序博客网 时间:2024/04/29 18:20

/*dlist.h*/

#ifndef DLIST_H_INCLUDE
#define DLIST_H_INCLUDE


#include <stdlib.h>


/*Define a structure for double-linked elements*/
typedef struct DListElmt_
{
    void *data;
    struct DListElmt_ *prev;
    struct DListElmt_ *next;
}DListElmt;


/*Define a structure for double-linked list */
typedef struct DList_
{
    int size;
    int (*match)(const void *key1, const void *key2);
    void (*destroy)(void *data);
    DListElmt *head;
    DListElmt *tail;
}DList;


#define dlist_size(list) ((list)->size)
#define dlist_head(list) ((list)->head)
#define dlist_tail(list) ((list)->tail)
#define dlist_is_head(element) (NULL == (element)->prev?1:0)
#define dlist_is_tail(element) (NULL == (element)->next?1:0)
#define dlist_data(element) ((element)->data)
#define dlist_next(element) ((element)->next)
#define dlist_prev(element) ((element)->prev)


void dlist_init(DList *list, void (*destroy)(void *data));
void dlist_destroy(DList *list);
int dlist_ins_next(DList *list, DListElmt *element, void *data);
int dlist_ins_prev(DList *list, DListElmt *element, void *data);
int dlist_remove(DList *list, DListElmt *element, void **data);


#endif // DLIST_H_INCLUDE


/*dlist.c*/

#include<stdio.h>
#include<string.h>
#include "dlist.h"


/*Init double list*/
void dlist_init(DList *list, void (*destroy)(void *data))
{
    list->size = 0;
    list->destroy = destroy;
    list->head = NULL;
    list->tail = NULL;


    return;
}


/*Destroy the list*/
void dlist_destroy(DList *list)
{
    void *data = NULL;


    if (0 != dlist_size(list) && NULL != list->destroy)
    {

/*Delete the last element*/
        if (0 == dlist_remove(list, dlist_tail(list), (void **)&data))
        {
            list->destroy(data);
        }
    }


    memset(list, 0, sizeof(DList));
    return;
}


/*Dlist insert after a element*/
int dlist_ins_next(DList *list, DListElmt *element, void *data)
{
    DListElmt *new_element = NULL;


    /*Do not allow insert after pointer NULL while the list is not empty */
    if (NULL == element && dlist_size(list) != 0)
    {
        return -1;
    }
    new_element = (DListElmt *)malloc(sizeof(DListElmt));
    if (NULL == new_element )
    {
        return -1;
    }


    new_element->data = data;


    /*Insert the new element into the list*/
    if (NULL == element)
    {
        new_element->next = NULL;
        new_element->prev = NULL;
        list->head = new_element;
        list->tail = new_element;
    }
    else
    {
        new_element->next = element->next;
        new_element->prev = element;
        if (NULL == element->next)
        {
            list->tail = new_element;
        }
        else
        {
            element->next->prev = new_element; /*error:userd element*/
        }
        element->next = new_element;
    }


    list->size++;
    return 0;
}
int dlist_ins_prev(DList *list, DListElmt *element, void *data)
{
    DListElmt *new_element = NULL;


    /*Do not allow insert before a NULL unless the list is empty*/
    if (NULL == element && 0 != dlist_size(list))
    {
        return -1;
    }


    new_element = (DListElmt *)malloc(sizeof(DListElmt));
    if (NULL == new_element)
    {
        return -1;
    }
    /*Insert the new element into the list*/
    if (NULL == element)
    {
        new_element->next = NULL;
        new_element->prev = NULL;
        list->head = new_element;NULL;
        list->tail = new_element;NULL;
    }
    else
    {
        new_element->next = element;
        new_element->prev = element->prev;
        if (NULL == element->prev)
        {
            list->head = new_element;
        }
        else
        {
            element->prev->next = new_element;
        }
        element->prev = new_element;
    }


    list->size--;
    return 0;
}
int dlist_remove(DList *list, DListElmt *element, void **data)
{
    /*Do not allow removal a NULL of remove from a empty list*/
    if (NULL == element || 0 == dlist_size(list))
    {
        return -1;
    }


    /*Remove the element from the list*/
    *data = element->data;


    if (list_is_head(element))
    {
        list->head = element->next;
        if (NULL == list->head)
        {
            list->tail = NULL;
        }
        else
        {
            element->next->prev = NULL;
        }
    }
    else
    {
        element->prev->next = element->next;
        if (NULL == element->next)
        {
            list->tail = element->prev;
        }
        else
        {
            element->next->prev = element->prev;
        }
    }
    free(element);
    /*Adjust list size*/
    list->size--;
    return 0;
}

Modify the red zone which is errno.

0 0