一、循环链表概念
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。
循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。在循环链表中可以定义一个"当前"指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。
二、循环链表的特点
循环链表的特点如下:
最后一个节点的指针指向第一个节点,形成闭环。
可以通过任意节点进行遍历,每个节点都有下一个节点的指针。
在遍历时可以无限循环下去,不会出现尾部节点的空指针错误。
可以从任意节点开始遍历,选择一个合适的起始节点可提高操作效率。
不增加额外存储花销
三、循环链表的基础运算
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。循环链表的基本运算包括插入、删除、修改、查询等,下面简单介绍这些基本运算的算法:
- 插入
在循环链表的任意位置插入一个新节点,需要修改插入位置的前驱节点的指针,使其指向新节点,然后将新节点的指针指向其下一个节点。
2.删除
在循环链表中删除一个节点,需要修改被删除节点的下一个节点的指针,使其指向被删除节点的上一个节点。
3.修改
在循环链表中修改一个节点的值,只需要修改该节点的值即可,不需要修改其他节点的指针。
4.查询
在循环链表中查询一个节点是否为某个值,需要遍历链表,直到找到该节点或者遍历到链表的末尾。
四、循环链表的实现过程
(一)、初始化链表
{
if(1)
{
/*申请内存*/
(*Head) = (SingleLinkList*)malloc(sizeof(SingleLinkList));
/*判断内存申请是否成功*/
if(*Head == NULL)
{
printf("申请内存错误, 初始化失败![100001]\n");
return 100001;
}
(*Head)->next = *Head;
return 0;
}
else
{
printf("该链表已经初始化!请删除后再执行此操作![100002]\n");
return 100002;
}
}
(二)、插入元素(头插法)
int insert_head(SingleLinkList **Head, DataType x)
{
SingleLinkNode *newNode;
if(0)
{
printf("链表未初始化![100003]\n");
return 100003;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
if(!newNode)
{
printf("申请节点内存空间失败![100004]\n");
return 100004;
}
newNode->data = x;
newNode->next = (*Head)->next;
(*Head)->next = newNode;
return 0;
}
(三)、插入元素(尾插法)
int insert_tail(SingleLinkList **Head, DataType x)
{
SingleLinkNode *newNode;
SingleLinkNode *p;if(0)
{
printf("链表未初始化![100003]\n");
return 100003;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
if(!newNode)
{
printf("申请节点内存空间失败![100004]\n");
return 100004;
}newNode->data = x;
newNode->next = *Head;
p = (*Head);while(p->next!=*Head)
{
p = p->next;
}
p->next = newNode;