数据结构:循环链表
循环链表是另一种形式的链式存储结构,其特点是最后一个节点的指针指向链表的第一个节点,形成一个闭环。本文将详细介绍如何在C语言中实现循环链表。
1.循环链表的基本结构
1.1节点结构体的定义
//结点的构建
typedef int ElemType;
typedef struct LNode {
ElemType data; //数据域
struct LNode* next; //节点域
}LNode,*LinkNode;
1.2循环链表的初始化
//循环链表初始化
void InitLinkList(LinkNode L,int initdata) {
L = (LNode*)malloc(sizeof(LNode)); //向内存请求存储空间
L->data = initdata;
L->next = L; //使头结点指向自己
}
2.循环链表的一些基本的操作
2.1插入节点
在循环链表中插入节点可以有不同的位置,例如在头部、尾部或指定位置。以下是在尾部插入节点的示例:
void InsertTail(LinkNode* L, ElemType e) {
LinkNode newNode = (LinkNode)malloc(sizeof(LNode));
if (newNode == NULL) {
fprintf(stderr, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
newNode->data = e;
newNode->next = L->next; // 新节点的next指向头节点的next
L->next = newNode; // 头节点的next指向新节点
}
2.2删除节点
void DeleteNode(LinkNode* L, ElemType e) {
LinkNode current = L, prev = NULL;
while (current->next != L && current->data != e) {
prev = current;
current = current->next;
}
if (current->data == e) {
if (prev == NULL) { // 删除头节点
L = current->next;
} else {
prev->next = current->next;
}
free(current);
} else {
printf("Element not found\n");
}
}
2.3遍历循环链表
遍历循环链表是查看链表中所有节点数据的一种方法。由于循环链表的特性,需要特别注意避免无限循环:
void TraverseList(LinkNode L) {
if (L == NULL) return;
LinkNode current = L->next; // 从头节点的next开始遍历
do {
printf("%d ", current->data);
current = current->next;
} while (current != L->next); // 当遍历回到头节点的next时停止
printf("\n");
}
2.4清空循环链表
void ClearList(LinkNode* L) {
LinkNode current = L, nextNode;
while (current != L) {
nextNode = current->next;
free(current);
current = nextNode;
}
free(L);
L = NULL;
}
2.5寻找节点
LinkNode FindNode(LinkNode L, ElemType e) {
LinkNode current = L->next; // 从头节点的next开始遍历
do {
if (current->data == e) {
return current;
}
current = current->next;
} while (current != L->next); // 当遍历回到头节点的next时停止
return NULL;
}