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; }