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

同单链表相似,循环链表中的每个元素也包含两个部分:一个数据域指针和一个指向后继元素的next指针。

数据结构CListElmt代表循环链表中的单独元素。该结构体拥有两个成员,如上面所述。

数据结构CList代表循环链表。这个结构体同单链表相似,但它不包含tail成员。

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

/*CList.h*/
#ifndef CLIST_H
#define CLIST_H

#include <stdio.h>

/*定义循环链表中元素的数据结构*/
typedef struct CListElmt_
{
    void *data;
    struct CListElmt_ *next;
} CListElmt;

/*定义循环链表的数据结构*/
typedef struct CList_
{
    int size;
    int (*match)(const void *key1,const void *key2);
    void (*destroy)(void *data);
    CListElmt *head;
} CList;

/*Public Interface*/
void clist_init(CList *list,void (*destroy)(void *data));
void clist_destroy(Clist *list);
int clist_ins_next(CList *list,CListElmt *element,const void *data);
int clist_rem_next(CList *list,CListElmt *element,void **data);

#define clist_size(list)((list)->size)
#define clist_head(list)((list)->head)
#define clist_data(element)((element)->data)
#define clist_next(element)((element)->next)

#endif // CLIST_H

接口定义的相关描述,请参阅循环链表接口定义

示例2:循环链表抽象数据类型的实现

/*clist.c*/
#include <stdio.h>
#include <string.h>

#include "clist.h"

/*clist_init  初始化循环链表*/
void clist_init(Clist *list,void (*destroy)(void *data))
{
    list->size = 0;
    list->destroy = destroy;
    list->head = NULL;
    
    return ;
}

/*clist_destroy  销毁循环链表*/
void clist_destroy(CList *list)
{
    void *data;
    /*移除所有元素*/
    while(clist_size(list)>0)
    {
        if(clist_rem_next(clist,element,void **data) == 0
           && list->destroy != NULL)
        {
            /*调用自定义函数释放动态分配的数据空间*/
            list->destroy(data);
        }
    }
    /*链表不允许再有任何操作,清空链表结构*/
    memset(list,0,sizeof(CList));
    return ;
}
/*clist_ins_next  向循环链表中插入元素*/
int clist_ins_next(CList *list,CListElmt *element,const void *data)
{
    CListElmt *new_element;
    
    /*为新元素分配空间*/
    if((new_element=(CListElmt *)malloc(sizeof(CListElmt)))==NULL)
        return -1;
    
    /*向链表中插入元素*/
    new_element->data = (void *)data;
    
    if(clist_size(list)==0)
    {
        /*当链表为空时的插入操作*/
        new_element->next = new_element;  /*元素的next指针指向元素本身*/
        list->head = new_element;         /*链表头指针指向插入元素*/
    }
    else
    {
        /*链表非空时的插入操作*/
        new_element->next = element->next;
        element->next =new_element;
    }
    /*变更链表的元素数量*/
    list->size++;
    return 0;
}

/*clist_rem_next  移除链表中的元素*/
int clist_rem_next(CList *list,CListElmt *element,void **data)
{
    CListElmt *old_element;
    
    /*空链表不允许有移除操作*/
    if(clist_size(list)==0)
        return -1;
    
    /*从链表中移除元素*/
    *data = element->next->data;
    if(element->next == element)  /*链表中只有一个元素*/
    {
        /*移除最后一个元素的操作*/
        old_element = element->next;
        list->head = NULL;
    }
    else
    {
        /*移除非最后一个元素的操作*/
        old_element=element->next;
        element->next=element->next->next;
        if(old_element == clist_head(list))  /*被移除元素位于头部*/
            list->head = old_element->next;
    }
    /*释放空间*/
    free(old_element);
    
    /*变更链表中元素的数量*/
    list->size--;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值