循环链表包括循环单链表和循环双链表
循环单链表的结点类型与非循环单链表相同,把非循环单链表改成循环单链表只需要将非循环单链表的尾结点next指针由原来的NULL改为指向头节点,自此就将非循环单链表形成看一个环,从表中的任一结点出发均可找到链表中其他的结点,这就是带头节点的循环单链表。
循环单链表的操作与单链表基本一致,差别在于遍历链表时,判别当前指针p是否指向表尾结点的终止条件不同:
单链表:p->next != NULL
循环单链表:p->next != h
如下是循环单链表:
空循环单链表:
下面附上循环单链表的完整代码:
#include <stdio.h>
typedef int ElemType;
typedef struct Node
{
ElemType data;//存储线性表的元素值(1个)
struct Node *next;//存储后继元素节点的地址
}SCLinkList;
/*
让最后一个节点的后继变成头节点
为了方便操作,特别地加了一个头节点进来,类型和普通节点一样
data:不用
next:存储第1个元素节点的地址
执行语句p=p->next;一次,p的指向往后移动一个位置
空:h->next==h
最后一个节点:若p->next==h,说明p指向最后一个节点
*/
/*
1.初始化
构造一个空的线性表
*/
SCLinkList *InitList()
{
SCLinkList *h;
h=(SCLinkList *)malloc(sizeof(SCLinkList));
h->next=h;
return h;
}
/*
2.销毁
*/
void DestroyList(SCLinkList *h)
{
int ListDelete(SCLinkList *h,int i,ElemType *e);
ElemType v;
while(h->next!=h)//不空
{
//删除第1个元素节点
ListDelete(h,1,&v);
}
free(h);
}
/*
3.判断线性表是否为空
若为空,返回1;
否则,返回0
*/
ListEmpty(SCLinkList *h)
{
if(h->next==h)
{
return 1;
}
else
{
return 0;
}
}
/*
4.求长度
*/
int ListLength(SCLinkList *h)
{
SCLinkList *p;
int len;
p=h;
len=0;
while(p->next!=h)
{
p=p->next;
len=len+1;
}
return len;
}
/*
5.输出
*/
void DispList(SCLinkList *h)
{
SCLinkList *p;
p=h;
printf("线性表的元素为:");
while(p->next!=h)
{
p=p->next;
printf("%d ",p->data);
}
printf("\n");
}
/*
6.取值
参数合法:i>=1 && i<=ListLength(h)
若参数合法,进行相关操作,返回1;
否则,提示,返回0
*/
int GetElem(SCLinkList *h,int i,ElemType *e)
{
SCLinkList *p;
int j;
if(i>=1 && i<=ListLength(h))
{
p=h;
for(j=1;j<=i;j++)
{
p=p->next;
}
*e=p->data;
return 1;
}
else
{
printf("参数错误!\n");
return 0;
}
}
/*
7.查找
在线性表中查找是否存在值为e的元素,
若存在,返回该元素的位序
否则,返回0
*/
int LocateElem(SCLinkList *h,ElemType e)
{
SCLinkList *p;
int len;
p=h;
len=0;
while(p->next!=h)
{
p=p->next;
len=len+1;
if(p->data==e)
{
return len;
}
}
return 0;
}
/*
8.添加
参数合法:i>=1 && i<=ListLength(h)+1
若参数合法,进行相关操作,返回1;
否则,提示,返回0
*/
int ListInsert(SCLinkList *h,int i,ElemType e)
{
SCLinkList *p,*q;
int j;
if(i>=1 && i<=ListLength(h)+1)
{
//1.构造一个节点q,存储元素e
q=(SCLinkList *)malloc(sizeof(SCLinkList));
q->data=e;
//2.让p指向第i-1个元素节点
p=h;
for(j=1;j<=i-1;j++)
{
p=p->next;
}
//3.添加
q->next=p->next;
p->next=q;
return 1;
}
else
{
printf("参数错误!\n");
return 0;
}
}
/*
9.删除
参数合法:i>=1 && i<=ListLength(h)
若参数合法,进行相关操作,返回1;
否则,提示,返回0
*/
int ListDelete(SCLinkList *h,int i,ElemType *e)
{
SCLinkList *p,*q;
int j;
if(i>=1 && i<=ListLength(h))
{
//1.让p指向第i-1个
p=h;
for(j=1;j<=i-1;j++)
{
p=p->next;
}
//2.让q指向第i个
q=p->next;
//3.把要删除的元素值存储到*e中
*e=q->data;
//4.删除
p->next=q->next;
//5.释放存储空间
free(q);
return 1;
}
else
{
printf("参数错误!\n");
return 0;
}
}
/*
变量先定义,再赋初值,才能使用
*/
int main()
{
/*
int a;
int b;
b=a*10;
printf("%d\n",b);*/
/*
int *p;
p=(int *)malloc(sizeof(int));
*p = 123;
printf("%d\n",*p);
free(p);
*/
return 1;
}