#数据#在本篇文章中,作者将与大家一起了解和学习循环链表,以及与循环链表相关的一些操作。
循环链表是也是一种链式存储结构,而与普通链表不同的是,循环链表的的最后一个结点指向头结点,形成了一个环。
循环链表包括了循环单链表与循环双链表,接下来我们一一来了解。
一,循环单链表:
一个循环单链表其实就是在初始化一个普通单链表时,将其头指针指向表头,而不是指向NULL,这样就构成了一个闭环,以下是使用c++代码初始化一个循环带链表:
循环单链表typedefstructNode{
intdata;
structNode*next;
}Node,*LinkList;
intListInit_L(LinkListL){
L=(LinkList)malloc(sizeof(Node));
L-next=L;
return1;
}
而与普通单链表相比,循环单链表会以头结点的next指针是否指向头而判断其是否为一个空表。
同时会以最后一个元素p的next指针是否指向头结点来判断是否以遍历到了表尾,以下是代码实现:
一个普通链表boolEmpty(LinkListl){
if(l-next==l){
returntrue;
//TODO
}else{
returnfalse;
}
}//判断循环单链表是否为空
boolisTail(LinkListl,Node*p){
if(p-next==l){
returntrue;
//TODO
}else{
returnfalse;
}
}//判断p指向的结点是否为该表的最后一个结点
二,循环双链表:
循环双链表其实就是将其头结点的prior指针指向尾部,尾结点的next指针指向头部。而我们可以通过观察头结点的next指针是否指向头结点来判断表是否为空。
通过观察p结点的next指针是否指向头结点来判断该元素是否为表尾元素,下面的循环双链表相关的代码实现:
初始化时的循环双链表1,初始化:
typedefstructDNode{
intdata;
structDNode*prior,*next;
}DNode,*DLinklist;
boolInitDList(DLinklistL){
L=(DNode*)malloc(sizeof(DNode));
if(L==NULL){
returnfalse;
//TODO
}
L-prior=L;
L-next=L;//与普通双链表不同之处就是将l的两个指针都指向了它本身
returntrue;
}
循环双链表2,插入操作:
boolInsterNextDNode(DLinklistp,DLinklists){
if(p==NULL
s==NULL){
returnfalse;
//TODO
}
s-next=p-next;
p-next-prior=s;
//TODO
s-prior=p;
p-next=s;
returntrue;
}//我们发现,循环双链表的插入操作不需要再考虑p的next指向空的情况,简化了代码
3,删除操作:
boolDeleteNextDNode(DLinklistp){
if(p==NULL){
returnfalse;
//TODO
}
DNode*q=p-next;
p-next=q-next;
q-next-prior=p;
//TODO
free(q);
returntrue;
}//同样,在进行删除操作时,也可以简化代码,不必再考虑p的next指向空的情况
本篇文章到此就结束了,欢迎大家