C算法精解---链表(2)

  前面对单链表和双链表的定义和抽象数据类型进行简单的介绍。下面介绍另外一种链表,循环链表。他提供了一种更灵活的遍历链表元素的能力,循环链表可以是单向的也可以是双向的。区分链表是循环链表的主要看他最后一个元素的next指针是不是指向的头元素。下面是以单向链表来介绍。

循环链表的实现和分析:

#ifndef CLIST_H
#define CLIST_H

#include <stdlib.h>
/*define a structure for linked CList elements */
typedef struct CListElmt_{
    void *data;
    struct CListElmt_ *next;
}CListElmt;

/*define a structure for linked clists */
typedef struct CList_ {
    int size;
    int (*match)(const void * key1, const void * key2);
    void (*destroy)(void *data);
    CListElmt *head;
}CList;

/*Public Intefaces */
void clist_init(CList *clist, void (*destroy)(void *data));
void clist_destory(CList *clist);
int clist_ins_next(CList *clist, CListElmt *element, const void *data);
int clist_rem_next(CList *clist, CListElmt *element, void *data);

#define clist_size(clist)            ((clist) -> size)
#define clist_head(clist)           ((clist) -> head)
#define clist_is_head(clist, element)    ((element) == (clist) -> head ? 1:0)
#define clist_data(element)          ((element) -> data)
#define clist_next(element)          ((element) -> next)

#endif


 

/*cclist.c*/
#include <studio.h>
#include <string.h>

#include "../include/Clist.h"

/*clist_init */
void clist_init(List * clist, void(* destroy)(void * data)) {
    /* initialize the clist */
    clist -> size = 0;
    clist -> destroy = destroy;
    clist -> head = NULL;

    return ;
}

/*clist_destroy */
void clist_destory(List * clist) {
    void *data;
    /*Remove eah element */
    while (clist_size(clist) > 0){
        if (clist_rem_next(clist, clist->head, (void **)  &data) == 0 && clist -> destroy 
        != NULL){
        /* Call a user-defined function to free dynamically allocated data*/
            clist ->destroy(data);
        }
    }
    memset(clist, 0, sizeof(CList));
    return;
}

/*clist_ins_nest */
int clist_ins_next (List * clist, CListElmt * element, const void * data){
    CListElmt *new_element;

    /* Allocate storage for the element */
    if ((new_element = (CListElmt *)malloc(sizeof(CListElmt))) == NULL){
        return -1;
    }

    /*insert the element into the clist */
    new_element ->data =(void *)data;
    if (clist_size(clist) == 0){
        new_element ->next = new_element;
        clist -> head = new_element;
    } else {
        /*Handle insertion somewhere other than at the head */
        
        new_element ->next = element ->next;
        element->next = new_element;
           
        }
    clist->size ++;
    return 0;
    
}
/* clist_rem_next */
int clist_rem_next(CList * clist, CListElmt * element, void * data) {
    CListElmt *old_element;

    /* do not allow the empty clist */
    if (clist_size(clist) == 0){
        return -1;
    }
    /*remove the element from the list */
    *data = element->next->data;
    if (element->next == element){
        old_element = element->next;
        clist->head = NULL;
    } else {
        old_element = element->next;
        if (element->next == clist->head){
            clist->head = element->next->next;
        } 
        element->next = element->next->next;
        
    }

    free(old_element);
    clist->size--;
    
    return 0;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值