什么是循环单链表
循环单链表是一种特殊的单链表,它与普通单链表的区别在于最后一个节点的指针不是空(null),而是指向链表的头节点,形成一个循环。
循环单链表的特点
-
循环性质: 循环单链表的最后一个节点指向第一个节点,形成一个环状结构。这使得链表的遍历和操作更为灵活。
-
无需特殊处理尾节点: 由于循环单链表中最后一个节点的指针指向头节点,插入和删除操作不需要特殊处理尾节点,简化了链表的操作
基本操作
初始化
初始化一个循环单链表时,头节点的 next
指针指向自身,形成一个空的循环。
head->next = head;
插入操作
插入新节点可以在头部或者尾部进行。在循环单链表中,插入操作相对简单。
在头部插入新节点
newNode->next = head->next;
head->next = newNode;
在尾部插入新节点
newNode->next = head;
previousNode->next = newNode;
删除操作
删除节点同样可以在头部或者尾部进行。
在头部删除节点
temp = head->next;
head->next = temp->next;
free(temp);
在尾部删除节点
temp = head;
while (temp->next != previousNode) {
temp = temp->next;
}
temp->next = head;
free(previousNode);
遍历操作
遍历循环单链表需要注意循环的终止条件。可以使用 while
循环,当遍历到头节点时停止。
temp = head->next;
while (temp != head) {
// 处理当前节点
// ...
temp = temp->next;
}
小结
循环单链表在某些场景中比普通单链表更为方便,例如用于循环遍历,模拟循环队列等情况。
循环单链表在操作上与普通单链表有相似之处,但由于循环的特性,某些情况下更为简便。在实际应用中,需要谨慎处理循环的终止条件,以防止出现死循环。
完整代码实现
#include<stdlib.h>
#include<stdio.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
//初始化循环单链表
bool InitList(LinkList &L){
L=(LNode *)malloc(sizeof(LNode));//分配头节点
//内存满了,分配失败
if(L==NULL){
return false;
}
L->next=L;//头节点下一个节点指向头节点
return true;
}
//循环单链表判空
bool Empty(LinkList L){
if(L->next==L){
return true;
}
return false;
}
//判断节点p是否为循环单链表的表尾节点
bool isTail(LinkList L,LNode *p){
if(p->next==L){
return true;
}
return false;
}
//循环单链表表尾节点的插入
bool InsertList(LinkList L,LNode *p){
if(p==NULL){
return false;
}
LNode *s;
s=L;
while(s->next!=L){
s=s->next;
}
//s到达表尾;
p->next=s->next;
s->next=p;
return true;
}
//删除最后一个节点
bool DeleteList(LinkList &L){
if(L->next==L || L==NULL){
return false;
}
LNode *s;
s=L;
while(s->next->next!=L){
s=s->next;
}
//s到达表尾前一个;
LNode *p;
//p为表尾节点
p=s->next;
s->next=p->next;
free(p);
return true;
}
int main(){
LinkList a;
bool bo=InitList(a);
if(bo){
printf("1");
}
else {
printf("0");
}
return 0;
}