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