Clist循环链表的实现

https://github.com/liutianshx2012/Algorithms-Data_structures/tree/master/Data_structures/src2

//
//  Clist.h
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-2.
//  Copyright (c) 2015年 TTc. All rights reserved.
//
/**
 *  循环链表
 */
#ifndef __Algorithms_Data_structures__Clist__
#define __Algorithms_Data_structures__Clist__

#include <stdlib.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;

void cprint_list(const CList *clist);

/*Public Intefaces */
void clist_init(CList *clist, void (*destroy)(void *data));

void clist_destroy(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 /* defined(__Algorithms_Data_structures__Clist__) */
//
//  Clist.c
//  Algorithms&Data_structures
//
//  Created by TTc on 15-2-2.
//  Copyright (c) 2015年 TTc. All rights reserved.
//

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

//O(1)
void
clist_init(CList *clist, void (*destroy)(void *data)){
    clist->size = 0;
    clist->destroy = destroy;
    clist->head = NULL;
}
//O(n)
void
clist_destroy(CList *clist){
    void *data;
    //remove each element
    while (clist_size(clist) != 0) {
        if(clist_rem_next(clist, clist->head, (void**) &data) == 0 && clist->destroy != NULL){
            clist->destroy(data);
        }
    }
    //clist清除
    memset(clist, 0, sizeof(CList));
}
/* 1: insert操作
 */
/* 插入成功返回0 ,反之返回 -1 */

/* 将元素插入由list指针的循环链表中element之后,

 当插入空链表中时,element可能指向
 任何位置,为了避免混淆,element此时应该设置为NULL。

 新的元素包含一个指向data的指针,
 因此只要该元素仍在链表中,data所引用的内存空间就应该保持合法.由调用者负责管理data
 所引用的存储空间.
 */
/* O(1)*/
int
clist_ins_next(CList *clist, 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(clist) == 0){
        new_element->next = new_element;
        clist->head = new_element;
    }else{ //非空表时候的操作操作
        new_element->next = element->next;
        element->next = new_element;
    }
    //size自增
    clist->size++;
    return 0;
}

/* 1: remove操作:将移除由参数list指定的 循环表中element后面的元素 。
 2: 返回时候 data指向已经 移除元素中存储的数据
 3: 由调用者负责管理于data想关联的内存(存储空间)
 */
/* 删除成功返回0 ,反之返回 -1 */
/* O(1)*/

int
clist_rem_next(CList *clist, CListElmt *element, void **data){
    CListElmt *old_element;
    //不允许从一个空链表 移除节点
    if(clist_size(clist) == 0){
        return -1;
    }
    *data = element->next->data;
    //自己指向自己 (链表中只有一个元素的情况)
    if(element->next == element){
        /* handle  removing the last element*/
        old_element = element->next;
        clist->head = NULL;
    }
    else{
        /* handle  removing the last element*/
        old_element = element->next;
        element->next = old_element->next;
        //如果要删除的 元素 是头元素 则需要 特殊处理 (指向 要删除元素的 下一个位置的元素)
        if(old_element == clist_head(clist)){
            clist->head = old_element->next;
        }
    }
    free(old_element);
    clist->size --;
    return 0;
}



void
cprint_list(const CList *clist) {
    CListElmt *element = clist_head(clist);
    int *data;
    int i = 0;
    if(element != NULL){
        do{
            data = clist_data(element);
            printf("cprint_list======>list[%d]=%d\n", i, *data);
            element = element->next;
            i++;
        }while (element != clist_head(clist));
    }
}





#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "clist.h"


typedef struct Cuboid_
{
    int length;
    int width;
    int height;
}Cuboid;

Cuboid *
cube_instance(const int length, const int width, const int height)
{
    Cuboid *cb_ptr;
    cb_ptr = (Cuboid *)malloc(sizeof(Cuboid));
    if( cb_ptr == NULL )
        return NULL;

    cb_ptr->length = length;
    cb_ptr->width = width;
    cb_ptr->height = height;

    return cb_ptr;
}

/*destroy */
void destroy(void *data)
{
    free(data);
    return;
}

/* main */
int
main(int argc, char **argv)
{
    int i;
    int ret = 0;
    CList clist;
    CListElmt *p = NULL;

    Cuboid *cb1_ptr, *cb2_ptr, *cb3_ptr, *cb4_ptr, *cb5_ptr;
    Cuboid *cb_ptr;

    //cb1_ptr ~ cb5_ptr are the data of the 5 elements.
    cb1_ptr = cube_instance(1,2,3);
    cb2_ptr = cube_instance(6,10,8);
    cb3_ptr = cube_instance(5,20,30);
    cb4_ptr = cube_instance(17,100,25);
    cb5_ptr = cube_instance(3,6,9);

    //init the clist
    clist_init(&clist, destroy);

    //insert the above 5 element 
    /* cb1 -> cb1 */
    ret = clist_ins_next(&clist, NULL, (void *)cb1_ptr);
    if( ret != 0 )
    {
        printf("insert cb1 error\n");
        return -1;
    }

    /* cb1 -> cb2 -> cb1 */
    p = clist_head(&clist);
    ret = clist_ins_next(&clist, p, (void *)cb2_ptr);
    if( ret != 0 )
    {
        printf("insert cb2 error\n");
        return -1;
    }

    /* cb1 -> cb2 ->cb3 ->cb1*/
    p = clist_next(p);
    ret = clist_ins_next(&clist, p, (void *)cb3_ptr);
    if( ret != 0 )
    {
        printf("insert cb3 error\n");
        return -1;
    }

    /* cb1 -> cb2 -> cb3 -> cb4 ->cb1 */
    p = clist_next(p);
    ret = clist_ins_next(&clist, p, (void *)cb4_ptr);
    if( ret != 0 )
    {
        printf("insert cb4 error\n");
        return -1;
    }

    /* cb1 -> cb2 -> cb3 -> cb4 ->cb5 -> cb1 */
    p = clist_next(p);
    ret = clist_ins_next(&clist, p, (void *)cb5_ptr);
    if( ret != 0 )
    {
        printf("insert cb5 error\n");
        return -1;
    }

    p = clist_head(&clist); //get the head element
    for(i = 0; i < clist_size(&clist) + 1; i++ )
    {
        cb_ptr = (Cuboid *)clist_data(p); // get the element's data, every data is a Cuboid 's pointer.
        printf("i = %d: ",i);
        printf("length = %d, width = %d, height = %d\n",
                cb_ptr->length,
                cb_ptr->width,
                cb_ptr->height);
        p = clist_next(p); //pointer to next element.
    }

    //remove the head element 
    clist_rem_next(&clist, p, (void **)&cb_ptr);
    printf("the removed element: length = %d, width = %d, height = %d\n",
            cb_ptr->length,
            cb_ptr->width,
            cb_ptr->height);

    destroy(cb_ptr); //free the memeory

    //destroy the circle list 
    clist_destroy(&clist);
    printf("after destroy the list, its size = %d\n", clist_size(&clist));
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值