循环链表

原创 2015年11月18日 23:38:19

以下是循环单向链表的接口定义:

#ifndef _CLIST_H
#define _CLIST_H

#include <stdlib.h>

typedef struct CListElmt_
{
	void *data;
	struct CListElmt_ *next;
}CListElmt;

typedef struct CList_
{
	int size;
	void (*destroy)(void *data);
	void (*match)(const void *key1,const void *key2);
	CListElmt *head;
}CList;

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_next(element) ((element)->next)
#define clist_data(element) ((element)->data)

#endif  /* _CLIST_H */

下面是对接口内容的实现:

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


void clist_init(CList *list,void (*destroy)(void *data))
{
	list->size = 0;
	list->destroy = destroy;
	list->head = NULL;

	return;
}

void clist_destroy(CList *list)
{
	void *data;
	while(clist_size(list) > 0)
	{
		if(clist_rem_next(list,list->head,(void **)&data) == 0 && list->destroy != NULL)
			list->destroy(data);
	}
	memset(list,0,sizeof(CList));
	return;
}

int clist_ins_next(CList *list,CListElmt *element,const void *data)
{
	CListElmt *new_element;
	new_element = (CListElmt *)malloc(sizeof(CListElmt ));
	if(new_element == NULL)
		return -1;
	new_element->data = (void *)data;

	if(clist_size(list) == 0)
	{
		new_element->next = new_element;
		list->head = new_element;
	}
	else  //不存在最后一个元素,所有不需要考虑最后的元素
	{
		new_element->next = element->next;
		element->next = new_element;
	}
	list->size++;
	return 0;
}

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;
}
最后内容是利用这些API来实现一些小应用:

#include "list.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define SIZE 30
CList list;

typedef struct hello_
{
	int a;
	int b;
	int c;
}hello;

void destroy(void *data)
{
	printf("in destroy.\n");
	//free(data); 
	return;
}

hello *init(const int a,const int b,const int c)
{
	hello *ptr;
	ptr = (hello *)malloc(sizeof(hello));
	if(ptr == NULL)
		return NULL;
	ptr->a = a;
	ptr->b = b;
	ptr->c = c;

	return ptr;
}

//查找前驱指针
CListElmt *find_prev(int n)
{
	int i;
	CListElmt *elem;
	elem = clist_head(&list);
	for(i = 1;i < n;i++)
		elem = clist_next(elem);
	return elem;
}

//查找要删除的数据域指针
hello *find_data(int n)
{
	int i;
	hello *hel;
	CListElmt *elem;
	elem = clist_head(&list);
	for(i = 0;i < n;i++)
	{
		elem = clist_next(elem);
		hel = clist_data(elem);
	}
	return hel;
}

/* 遍历函数 */
void loop_print(void )
{
	int i;
	CListElmt *elem;
	hello *p;
	elem = clist_head(&list);
	for(i = 0;i < clist_size(&list);i++)
	{
		p = clist_data(elem);
		printf("a=%d b=%d c=%d\n",p->a,p->b,p->c);
		elem = clist_next(elem);
	}
}

/* 准备插入的元素 */
static const hello hello_zhm = {7,8,9};

int main(void)
{
	hello *hel;
	CListElmt *elem;
	clist_init(&list,destroy);
	printf("Init OK!\n");
	
	hello *ptr_1,*ptr_2,*ptr_3,*ptr_4,*ptr_5;
	ptr_1 = init(1,1,1);
	ptr_2 = init(2,2,2);
	ptr_3 = init(3,3,3);
	ptr_4 = init(4,4,4);
	ptr_5 = init(5,5,5);

	clist_ins_next(&list,NULL,(void *)ptr_1);
	elem = clist_head(&list);
	clist_ins_next(&list,elem,(void *)ptr_2);
	elem = clist_next(elem);
	clist_ins_next(&list,elem,(void *)ptr_3);
	elem = clist_next(elem);
	clist_ins_next(&list,elem,(void *)ptr_4);
	elem = clist_next(elem);
	clist_ins_next(&list,elem,(void *)ptr_5);
	loop_print();

	
	printf("remove the third .now it is ...\n");
	elem = find_prev(2);
	hel = find_data(2);
	clist_rem_next(&list,elem,(void **)&hel);
	loop_print();

	printf("after insert into a fouth node .now ..\n");
	elem = find_prev(3);
	clist_ins_next(&list,elem,(void *)&hello_zhm);
	loop_print();
	
	printf("free the list !\n");
	clist_destroy(&list);
	loop_print();
	printf("free success.\n");
	return 0;
}

下面是运行结果:


  1. (完毕)

版权声明:本文为博主原创文章,未经博主允许不得转载。

数据结构C#——循环链表

我曾经去一家游戏公司面试时遇到一个笔试题,大意就是说有一群人出去旅游,在河中遇到了大风,然后用转盘决定谁在留在船上,谁自己跳下去自行解决生存问题。大家围成一个圈,启动转盘,转盘指向谁就从睡开始数数,当...
  • luxin10
  • luxin10
  • 2011年01月03日 17:42
  • 3033

Java数据结构——循环链表的实现

一、描述 循环链表:表中的最后一个节点的指针域指向头结点,整个链表形成一个环。循环链表判空条件:有的说是判断p或p->next是否等于头指针,有的说判断tail是否等于head,有的说判断head是...
  • u013293125
  • u013293125
  • 2016年10月27日 21:22
  • 1623

数据结构学习之循环链表结构

注:本文的主要目的是为了记录自己的学习过程,也方便与大家做交流。转载请注明来自: http://blog.csdn.net/ab198604         循环链表在单向链表及双向链表的...
  • ab198604
  • ab198604
  • 2013年01月04日 17:55
  • 5474

(三)循环链表以及循环链表应用

单向循环链表 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环。和单链表相比,循环单链表的长处是从链尾到链头比...
  • FullyFang
  • FullyFang
  • 2013年10月04日 23:05
  • 1528

数据结构(9)线性表之循环链表介绍

导言 循环列表 循环列表结构 单循环列表实现代码 运行结果导言循环列表是链式存储结构的一种形式。它的特点从名字就可以清楚,“循环”。那么如何实现循环。 循环的实现很简单,只有表的最后一个结点的指针,...
  • YuYunTan
  • YuYunTan
  • 2016年03月16日 11:25
  • 1908

循环链表的实现与操作(C语言实现)

循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。 循环链表的操作 1,循环链表的新操作 2, 获取当前游标指向的数据元素 3, 将游标重置...
  • u010590318
  • u010590318
  • 2014年06月05日 14:55
  • 2352

循环链表(1) - 介绍以及应用

在下面的这两篇文章中,已经讨论过了单链表和双向链表的基本情况。 "单链表 - 基本介绍以及插入节点",点此链接。 "双向链表(1) - 基本介绍以及插入节点",点此链接。 循环链表是一个所有节点相...
  • shltsh
  • shltsh
  • 2015年06月15日 01:01
  • 1134

循环链表的创建及遍历

#include using namespace std; typedef int ElemType; typedef struct Node { ElemType elem; struct ...
  • v_yang_guang_v
  • v_yang_guang_v
  • 2015年04月06日 21:56
  • 7781

【数据结构】循环链表的建立与输出

因为循环链表就是讲单链表的最后一个结点的指针不置空,而是指向头结点的next域。因此这里就不加别的操作,建立后便输出,其他操作与单链表无异。 循环链表的建立与输出.cpp #include ...
  • qq_32353771
  • qq_32353771
  • 2015年11月10日 14:43
  • 4292

循环链表c++实现

#ifndef _CIRCLELINK_H_ #define _CIRCLELINK_H_ #include #include "CircleLink.hpp" using namespace...
  • u012967763
  • u012967763
  • 2014年12月19日 00:12
  • 820
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:循环链表
举报原因:
原因补充:

(最多只允许输入30个字)