/**
* 实验题目:
* 实现循环单链表各种基本运算的算法
* 实验内容:
* 编写一个程序实现循环单链表的各种基本运算,并在此基础上设计一个主程序
* 完成如下功能:
* (1)初始化循环单链表h
* (2)依次采用尾部插入法插入a,b,c,d,e元素
* (3)输出循环单链表h
* (4)输出循环单链表h长度
* (5)判断循环单链表h是否为空
* (6)输出循环单链表h的第3个元素
* (7)输出元素a的位置
* (8)在第4个元素位置上插入f元素
* (9)输出循环单链表h
* (10)删除h的第3个元素
* (11)输出循环单链表h
* (12)释放循环单链表h
*/
#include
#include
typedef char ElemType;
typedef struct LNode // 定义循环单链表结点类型
{
ElemType data; // 数据域
struct LNode *next; // 指针域
}LinkList;
/*-------------------------初始化循环单链表L------------------------*/
void InitList(LinkList *&L) // 指针的引用
{
L = (LinkList *)malloc(sizeof(LinkList)); // 创建头结点
L->next = L;
}
/*-------------------------释放循环单链表L------------------------*/
void DestroyList(LinkList *&L)
{
LinkList *p = L;
LinkList *q = p->next;
while(q != L)
{
free(p);
p = q;
q = p->next;
}
free(p);
}
/*-------------------------判断循环单链表L是否为空表------------------------*/
int ListEmpty(LinkList *L)
{
return (L->next == L); // 空表
}
/*-------------------------返回循环单链表L的元素个数------------------------*/
int ListLength(LinkList *L)
{
int i = 0;
LinkList *p = L;
while(p->next != L)
{
i++;
p = p->next;
}
return i;
}
/*-------------------------输出循环单链表L------------------------*/
void DispList(LinkList *L)
{
LinkList *p = L->next;
while(p != L)
{
printf("%c ", p->data);
p = p->next;
}
printf("\n");
}
/*-------------------------获取循环单链表L中的第i个元素------------------------*/
int GetElem(LinkList *L, int i, ElemType &e) // 引用
{
int j = 0;
LinkList *p;
if(L->next != L) // 单链表为非空表时
{
if(i == 1)
{
e = L->next->data; // 提取元素
return 1;
}
else // i不为1时
{
p = L->next;
while((p != L) && (j < i - 1))
{
j++;
p = p->next;
}
if(p == L)
return 0;
else // 找到第i个元素
{
e = p->data; // 提取元素
return 1;
}
}
}
else // 单链表为空表时
return 0;
}
/*-------------------------在循环单链表L中查找元素e------------------------*/
int LocateElem(LinkList *L, ElemType e)
{
int n = 1;
LinkList *p = L->next;
while((p != L) && (p->data != e))
{
p = p->next;
n++;
}
if(p == L)
return 0;
else
return n;
}
/*-------------------------在循环单链表L中第i个位置上插入元素e------------------------*/
int ListInsert(LinkList *&L, int i, ElemType e)
{
int j = 0;
LinkList *p = L, *s;
if((i == 1) || (p->next == L)) // 原单链表为空表或i=1时
{
s = (LinkList *)malloc(sizeof(LinkList)); // 创建新结点s
s->data = e;
s->next = p ->next; // 将s插入到p之后
p->next = s;
return 1;
}
else
{
p = L->next;
while((p != L) && (j < i - 2)) // 查找第i-1个结点
{
j++;
p = p->next;
}
if(p == L) // 未找到第i-1个结点
return 0;
else // 找到第i-1个结点
{
s = (LinkList *)malloc(sizeof(LinkList)); // 创建新结点s
s->data = e;
s->next = p->next; // 将s插入到p之后
p->next = s;
return 1;
}
}
}
/*-------------------------在循环单链表L中删除第i个元素------------------------*/
int ListDelete(LinkList *&L, int i, ElemType &e)
{
int j = 0;
LinkList *p = L, *q;
if(p->next != L) // 原单链表不为空表时
{
if(i == 1) // i=1时
{
q = L->next; // 删除第1个结点
e = q->data;
L->next = q->next;
free(q);
return 1;
}
else // i不为1时
{
p = L->next;
while((p != L) && (j < i - 2)) // 查找第i-1个结点
{
j++;
p = p->next;
}
if(p == L) // 未查找到第i-1个结点
return 0;
else // 查找到第i-1个结点
{
q = p->next; // q指向要删除的结点
e = q->data; // 提取元素
p->next = q->next; // 从单链表中删除q结点
free(q); // 释放q结点
return 1;
}
}
}
else
return 0;
}
int main(void)
{
LinkList *h;
ElemType e;
printf("(1)初始化循环单链表h\n");
InitList(h);
printf("(2)依次采用尾部插入法插入a,b,c,d,e元素\n");
ListInsert(h, 1, 'a');
ListInsert(h, 2, 'b');
ListInsert(h, 3, 'c');
ListInsert(h, 4, 'd');
ListInsert(h, 5, 'e');
printf("(3)输出循环单链表h:");
DispList(h);
printf("(4)循环单链表h长度=%d\n", ListLength(h));
printf("(5)循环单链表h为%s\n", (ListEmpty(h) ? "空" : "非空"));
GetElem(h, 3, e);
printf("(6)循环单链表h的第3个元素=%c\n", e);
printf("(7)元素a的位置=%d\n", LocateElem(h, 'a'));
printf("(8)在第4个元素位置上插入f元素\n");
ListInsert(h, 4, 'f');
printf("(9)输出循环单链表h:");
DispList(h);
printf("(10)删除h的第3个元素\n");
ListDelete(h, 3, e);
printf("(11)输出循环单链表h:");
DispList(h);
printf("(12)释放循环单链表h\n");
DestroyList(h);
return 0;
}
测试结果:
(1)初始化循环单链表h
(2)依次采用尾部插入法插入a,b,c,d,e元素
(3)输出循环单链表h:a b c d e
(4)循环单链表h长度=5
(5)循环单链表h为非空
(6)循环单链表h的第3个元素=c
(7)元素a的位置=1
(8)在第4个元素位置上插入f元素
(9)输出循环单链表h:a b c f d e
(10)删除h的第3个元素
(11)输出循环单链表h:a b f d e
(12)释放循环单链表h