前言
对于循环单链表而言,在进行插入和删除时,可以让指针指向尾部,对于表头(通过尾部找到头部)和表尾的操作的时间复杂度均为O(1);
一、循环单链表的初始化
//带头结点的循环单链表
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*Linklist;
bool Initlist(Linklist &L){
L=(LNode *)malloc(sizeof(LNode)); //分配一个头结点,且不存储任何数据
if(L==NULL)
return false; //内存不足,分配失败
L->next=L; //区别于单链表的初始化,头结点的next指向头结点
return ture;
}
二、判断是否为空或表尾结点
//判断循环单或双链表是否为空
bool Empty(Linklist L){
return(L->next==L);
}
//判断结点p是否是循环单或双链表的表尾结点
bool isTail(Linklist L,LNode *p){
return(p->next==L);
}
三、循环双链表的初始化
//初始化循环双链表
bool InitDLinklist(DLinklist &L){
L=(DLNode *)malloc(sizeof(DLNode)); //分配一个头结点,且不存储任何数据
if(L==NULL)
return false; //内存不足,分配失败
L->prior=L; //区别于循环单链表的初始化,头结点的prior指向头结点
L->next=L;
return ture;
}
四、循环双链表的插入与删除
//循环双链表的插入
bool InsertNextDNode(DNode *p,DNode *s){
s->next=p->next;
p->next->prior=s;
s->prior=p;
p->next=s;
}
//循环双链表的删除
bool DeleteDNode(DNode *p){
p->next=q->next;
q->next->prior=p;
free(q);
}