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