数据结构--循环单链表

循环单链表

循环单链表是单链表的另一种形式,其结构特点链表中最后一个结点的指针域不再是结束标记,而是指向整个链表的第一个结点,从而使链表形成一个环。和单链表相同,循环链表也有带头结点结构和不带头结点结构两种,带头结点的循环单链表实现插入和删除操作较为方便。一个带头结点的循环单链表如下图所示:

代码实例:

CSList.h

#ifndef CSLIST_H_
#define CSLIST_H_

typedef char ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode *next;	
}LinkList;

void InitList(LinkList *&L);

void DestoryList(LinkList *L);

int ListEmpty(LinkList *L);

int ListLength(LinkList *L);

void PrintList(LinkList *L);

int GetElem(LinkList *L,int n,ElemType &e);

int LocateElem(LinkList *L,ElemType e);

int InsertList(LinkList *&L,int n,ElemType e);

int ListDelete(LinkList *&L,int n,ElemType &e);
#endif

CSList.cpp

#include <iostream>
#include <malloc.h>
#include "CSList.h"
using namespace std;

void InitList(LinkList *&L)
{
	L=(LinkList*)malloc(sizeof(LinkList));
	L->next=L;//Create Header Node
}

void DestoryList(LinkList *L)
{
	LinkList *p=L,*q=L->next;
	while(q!=L)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}

int ListEmpty(LinkList *L)
{
	return (L->next==L);
}

int ListLength(LinkList *L)
{
	LinkList *p=L;
	int length=0;
	while(p->next!=L)
	{
		length++;
		p=p->next;
	}
	return length;
}

void PrintList(LinkList *L)
{
	LinkList *p=L->next;
	while(p!=L)
	{
		cout<<p->data<<'\t';
		p=p->next;
	}
	cout<<endl;
}
/*
*Get the ElemType e's location n
*/
int GetElem(LinkList *L,int n,ElemType &e)
{
	LinkList *p=L->next;
	int i=0;
	if(p!=L)//LinkList isnnot Empty
	{
		if(n==1)
		{
			e=p->data;
			return 1;
		}
		else
		{
			while(i<n-1&&p!=L)
			{
				i++;
				p=p->next;
			}
			if(p==L)//The latest LNode,traverse a cycle
				return 0;
			else
			{
				e=p->data;
				return 1;
			}
				
		}
	}
	else //LinkList is Empty.
		return 0;
}

/*
*Locate the Location of ElemType e 
*/
int LocateElem(LinkList *L,ElemType e)
{
	LinkList *p=L->next;
	int i=1;
	while(p!=L&&p->data!=e)
	{
		p=p->next;
		i++;
	}
	if(p==L)//The lastest LNode,ElemType e does not exist
		return 0;	
	else
		return i;
}

/*
*Insert a ElemType e in LinkList
*/
int InsertList(LinkList *&L,int n,ElemType e)
{
	LinkList *p=L,*q;
	int i=0;
	if(p->next==L||n==1)//the LinkList is Empty or the ElemType e is inserted the first location
	{
		q=(LinkList*)malloc(sizeof(LinkList));
		q->data=e;
		q->next=p->next;
		p->next=q;
		return 1;
	}
	else//链表不为空,且元素不是插在第一个位置
	{
		p=p->next;
		while(i<n-2&&p!=L)
		{
			i++;
			p=p->next;
		}
		if(p==L)//链表结点数小于n-1,也就是第n-1个结点不存在
			return 0;
		else
		{
			q=(LinkList*)malloc(sizeof(LinkList));
			q->data=e;
			q->next=p->next;
			p->next=q;
			return 1;
		}
	}
}

/*
*删除第n个结点,其值保存在e中
*/
int ListDelete(LinkList *&L,int n,ElemType &e)
{
	LinkList *p=L,*q;
	int i=0;
	if(p->next!=L)//链表不为空
	{
		if(n==1)//删除第一个结点(第一个结点是最后一个结点也是如此)
		{
			q=p->next;
			e=q->data;
			p->next=q->next;
			free(q);
			return 1;
		}
		else
		{
			p=p->next;
			while(i<n-2&&p!=L)//p不是最后一个结点或者没有达到第n个结点
			{
				i++;
				p=p->next;
			}
			if(p==L)//结点数小于n-1
				return 0;
			else
			{
				q=p->next;//q为实际要删除的结点
				e=q->data;
				p->next=q->next;
				free(q);
				return 1;
			}
		}
	}
	else
		return 0;
}

main.cpp

#include <iostream>
#include "CSList.h"

using namespace std;
int main()
{
	LinkList *L;
	ElemType e;
	cout<<"(1)初始化单链表L"<<endl;
	InitList(L);

	cout<<"(2)依次采用尾插入法插入a,b,c,d,e元素"<<endl;
	InsertList(L,1,'a');
	InsertList(L,2,'b');
	InsertList(L,3,'c');
	InsertList(L,4,'d');
	InsertList(L,5,'e');

	cout<<"(3)输出单链表"<<endl;
	PrintList(L);

	cout<<"(4)单链表的长度Length="<<ListLength(L)<<endl;
	cout<<"(5)判断单链表是否为空"<<endl;
	if (ListEmpty(L))
	{
		cout<<"单链表为空"<<endl;
	} 
	else
	{
		cout<<"单链表不为空"<<endl;
	}
	GetElem(L,3,e);
	cout<<"(6)顺序表L的第3个元素为="<<e<<endl;

	cout<<"(7)顺序表中元素c的位置i="<<LocateElem(L,'c')<<endl;

	cout<<"(8)在第4个元素位置上插入f元素"<<endl;
	InsertList(L,4,'f');
	cout<<"(9)输出顺序表"<<endl;
	PrintList(L);

	cout<<"(10)删除顺序表中的第3个元素"<<endl;
	ListDelete(L,3,e);																	
	cout<<"(11)输出顺序表L"<<endl;
	PrintList(L);

	cout<<"(12)释放顺序表L"<<endl;
	DestoryList(L);
	
	return 0;
}
实例结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值