循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。
]单向循环链表
存储结构和单链表相同。
/*
设立尾指针的单循环链表的12个基本操作
*/
void InitList(LinkList * L)
{ /* 操作结果:构造一个空的线性表L */
* L = (LinkList)malloc( sizeof ( struct LNode)); /* 产生头结点,并使L指向此头结点 */
if ( !* L) /* 存储分配失败 */
exit(OVERFLOW);
( * L) -> next =* L; /* 指针域指向头结点 */
}
void InitList(LinkList * L)
{ /* 操作结果:构造一个空的线性表L */
* L = (LinkList)malloc( sizeof ( struct LNode)); /* 产生头结点,并使L指向此头结点 */
if ( !* L) /* 存储分配失败 */
exit(OVERFLOW);
( * L) -> next =* L; /* 指针域指向头结点 */
}
void
DestroyList(LinkList
*
L)
{ /* 操作结果:销毁线性表L */
LinkList q,p = ( * L) -> next; /* p指向头结点 */
while (p !=* L) /* 没到表尾 */
{
q = p -> next;
free(p);
p = q;
}
free( * L);
* L = NULL;
}
{ /* 操作结果:销毁线性表L */
LinkList q,p = ( * L) -> next; /* p指向头结点 */
while (p !=* L) /* 没到表尾 */
{
q = p -> next;
free(p);
p = q;
}
free( * L);
* L = NULL;
}
void
ClearList(LinkList
*
L)
/*
改变L
*/
{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
LinkList p,q;
* L = ( * L) -> next; /* L指向头结点 */
p = ( * L) -> next; /* p指向第一个结点 */
while (p !=* L) /* 没到表尾 */
{
q = p -> next;
free(p);
p = q;
}
( * L) -> next =* L; /* 头结点指针域指向自身 */
}
{ /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
LinkList p,q;
* L = ( * L) -> next; /* L指向头结点 */
p = ( * L) -> next; /* p指向第一个结点 */
while (p !=* L) /* 没到表尾 */
{
q = p -> next;
free(p);
p = q;
}
( * L) -> next =* L; /* 头结点指针域指向自身 */
}
Status ListEmpty(LinkList L)
{ /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L -> next == L) /* 空 */
return TRUE;
else
return FALSE;
}
{ /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
if (L -> next == L) /* 空 */
return TRUE;
else
return FALSE;
}
int
ListLength(LinkList L)
{ /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0 ;
LinkList p = L -> next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i ++ ;
p = p -> next;
}
return i;
}
{ /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
int i = 0 ;
LinkList p = L -> next; /* p指向头结点 */
while (p != L) /* 没到表尾 */
{
i ++ ;
p = p -> next;
}
return i;
}
Status GetElem(LinkList L,
int
i,ElemType
*
e)
{ /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j = 1 ; /* 初始化,j为计数器 */
LinkList p = L -> next -> next; /* p指向第一个结点 */
if (i <= 0 || i > ListLength(L)) /* 第i个元素不存在 */
return ERROR;
while (j < i)
{ /* 顺指针向后查找,直到p指向第i个元素 */
p = p -> next;
j ++ ;
}
* e = p -> data; /* 取第i个元素 */
return OK;
}
{ /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j = 1 ; /* 初始化,j为计数器 */
LinkList p = L -> next -> next; /* p指向第一个结点 */
if (i <= 0 || i > ListLength(L)) /* 第i个元素不存在 */
return ERROR;
while (j < i)
{ /* 顺指针向后查找,直到p指向第i个元素 */
p = p -> next;
j ++ ;
}
* e = p -> data; /* 取第i个元素 */
return OK;
}
int
LocateElem(LinkList L,ElemType e,Status(
*
compare)(ElemType,ElemType))
{ /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
/* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int i = 0 ;
LinkList p = L -> next -> next; /* p指向第一个结点 */
while (p != L -> next)
{
i ++ ;
if (compare(p -> data,e)) /* 满足关系 */
return i;
p = p -> next;
}
return 0 ;
}
{ /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
/* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int i = 0 ;
LinkList p = L -> next -> next; /* p指向第一个结点 */
while (p != L -> next)
{
i ++ ;
if (compare(p -> data,e)) /* 满足关系 */
return i;
p = p -> next;
}
return 0 ;
}
Status PriorElem(LinkList L,ElemType cur_e,ElemType
*
pre_e)
{ /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
/* 否则操作失败,pre_e无定义 */
LinkList q,p = L -> next -> next; /* p指向第一个结点 */
q = p -> next;
while (q != L -> next) /* p没到表尾 */
{
if (q -> data == cur_e)
{
* pre_e = p -> data;
return TRUE;
}
p = q;
q = q -> next;
}
return FALSE; /* 操作失败 */
}
{ /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
/* 否则操作失败,pre_e无定义 */
LinkList q,p = L -> next -> next; /* p指向第一个结点 */
q = p -> next;
while (q != L -> next) /* p没到表尾 */
{
if (q -> data == cur_e)
{
* pre_e = p -> data;
return TRUE;
}
p = q;
q = q -> next;
}
return FALSE; /* 操作失败 */
}
Status NextElem(LinkList L,ElemType cur_e,ElemType
*
next_e)
{ /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
/* 否则操作失败,next_e无定义 */
LinkList p = L -> next -> next; /* p指向第一个结点 */
while (p != L) /* p没到表尾 */
{
if (p -> data == cur_e)
{
* next_e = p -> next -> data;
return TRUE;
}
p = p -> next;
}
return FALSE; /* 操作失败 */
}
{ /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
/* 否则操作失败,next_e无定义 */
LinkList p = L -> next -> next; /* p指向第一个结点 */
while (p != L) /* p没到表尾 */
{
if (p -> data == cur_e)
{
* next_e = p -> next -> data;
return TRUE;
}
p = p -> next;
}
return FALSE; /* 操作失败 */
}
Status ListInsert(LinkList
*
L,
int
i,ElemType e)
/*
改变L
*/
{ /* 在L的第i个位置之前插入元素e */
LinkList p = ( * L) -> next,s; /* p指向头结点 */
int j = 0 ;
if (i <= 0 || i > ListLength( * L) + 1 ) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1 ) /* 寻找第i-1个结点 */
{
p = p -> next;
j ++ ;
}
s = (LinkList)malloc( sizeof ( struct LNode)); /* 生成新结点 */
s -> data = e; /* 插入L中 */
s -> next = p -> next;
p -> next = s;
if (p ==* L) /* 改变尾结点 */
* L = s;
return OK;
}
{ /* 在L的第i个位置之前插入元素e */
LinkList p = ( * L) -> next,s; /* p指向头结点 */
int j = 0 ;
if (i <= 0 || i > ListLength( * L) + 1 ) /* 无法在第i个元素之前插入 */
return ERROR;
while (j < i - 1 ) /* 寻找第i-1个结点 */
{
p = p -> next;
j ++ ;
}
s = (LinkList)malloc( sizeof ( struct LNode)); /* 生成新结点 */
s -> data = e; /* 插入L中 */
s -> next = p -> next;
p -> next = s;
if (p ==* L) /* 改变尾结点 */
* L = s;
return OK;
}
Status ListDelete(LinkList
*
L,
int
i,ElemType
*
e)
/*
改变L
*/
{ /* 删除L的第i个元素,并由e返回其值 */
LinkList p = ( * L) -> next,q; /* p指向头结点 */
int j = 0 ;
if (i <= 0 || i > ListLength( * L)) /* 第i个元素不存在 */
return ERROR;
while (j < i - 1 ) /* 寻找第i-1个结点 */
{
p = p -> next;
j ++ ;
}
q = p -> next; /* q指向待删除结点 */
p -> next = q -> next;
* e = q -> data;
if ( * L == q) /* 删除的是表尾元素 */
* L = p;
free(q); /* 释放待删除结点 */
return OK;
}
{ /* 删除L的第i个元素,并由e返回其值 */
LinkList p = ( * L) -> next,q; /* p指向头结点 */
int j = 0 ;
if (i <= 0 || i > ListLength( * L)) /* 第i个元素不存在 */
return ERROR;
while (j < i - 1 ) /* 寻找第i-1个结点 */
{
p = p -> next;
j ++ ;
}
q = p -> next; /* q指向待删除结点 */
p -> next = q -> next;
* e = q -> data;
if ( * L == q) /* 删除的是表尾元素 */
* L = p;
free(q); /* 释放待删除结点 */
return OK;
}
void
ListTraverse(LinkList L,
void
(
*
vi)(ElemType))
{ /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi() */
LinkList p = L -> next -> next; /* p指向首元结点 */
while (p != L -> next) /* p不指向头结点 */
{
vi(p -> data);
p = p -> next;
}
printf( " \n " );
{ /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi() */
LinkList p = L -> next -> next; /* p指向首元结点 */
while (p != L -> next) /* p不指向头结点 */
{
vi(p -> data);
p = p -> next;
}
printf( " \n " );