// 实现单循环链表
#include <stdlib.h> // 引入标准库与输入输出库
#include <stdio.h>
typedef int ElemType;
// 定义带头结点的单链表
typedef struct node {
ElemType data;
struct node* link;
}LNode, *LoopLinkList;
// 初始化单循环链表
void InitList(LoopLinkList *L)
{
*L = (LoopLinkList)malloc(sizeof(struct node)); // 此时,*L是二级指针, L是一级指针
if (!(*L))
{
exit(-1);
}
(*L) -> link = *L; // 区别于非循环单链表: (*L) -> link = NULL
}
// 销毁单循环链表
// 1. 删除并释放每个结点
void DestroyList(LoopLinkList* L)
{
LoopLinkList p = (*L)->link,q; // 初始节点为头结点指向的单循环链表的第一个结点
while (p != *L) { // 判断条件区别于单链表
q = p->link; // 释放p结点,q作为临时变量,暂存p的链接
free(p);
p = q;
}
free(*L); // 释放头结点
*L = NULL; // 释放二级指针
}
void TraverseList(LoopLinkList L)
{
LoopLinkList p = L;
int i = 0;
while (p->link != L) {
p = p->link;
printf("Data value: %d
", p->data);
i++;
}
}
// 插入操作
void ListInsert(LoopLinkList *L, int i, ElemType E)
{
LoopLinkList p = *L; // 赋值,p赋值后,指向头结点
int j = 1;
while (j < i) { // p指向位置的移动,j表征移动的次数。p移动到插入位置的前一个结点
p = p->link;
j++;
}
LoopLinkList q = (LoopLinkList)malloc(sizeof(struct node));
q->data = E;
q->link = p->link;
p->link = q;
}
// 删除操作
void ListDelete(LoopLinkList* L, int i)
{
LoopLinkList p = *L, q; // p指向头结点(并非单循环链表的第一个结点)
int j = 0;
while (j < i - 1) // 跳出循环的条件就是:j=i-1,此时p移动到了i-1的位置
{
p = p->link;
j++;
}
q = p->link; // 临时结点q指向i位置,将指向转移到前一结点后,释放q结点
p->link = q->link;
free(q);
}
// 将原有链表置为空表
void ClearList(LoopLinkList *L)
{
LoopLinkList p = *L, q;
while (p ->link != *L) // p指向要删除结点的前一结点,q暂存要删除的结点
{
q = p->link;
p->link = q->link;
free(q);
}
//printf("地址:%d, %d", *L, (*L)->link);
}
// 单循环链表长度
int ListLength(LoopLinkList L)
{
/*LoopLinkList p = *L;
int i = 0;
while (p->link != *L) {
p = p->link;
i++;
}
return i;*/
int i = 0;
LoopLinkList p = L->link;
while (p != L) {
i++;
p = p->link;
}
return i;
}
int main()
{
LoopLinkList L;
InitList(&L);
ListInsert(&L, 1, 1);
ListInsert(&L, 1, 2);
ListInsert(&L, 1, 3);
ListInsert(&L, 1, 4);
ListInsert(&L, 1, 5);
printf("长度:%d
", ListLength(L));
TraverseList(L);
ListDelete(&L, 2);
ClearList(&L);
printf("长度:%d
", ListLength(L));
TraverseList(L);
return 0;
}