单向循环链表
前言
在我们学习完单链表后,我们发现,如果我们要周而复始的访问链表的结点,用单链表并不方便,所以我们就研究了循环链表的使用。
一、循环链表是什么?
1.形态:
环状的链表(无头无尾)
——好处:可以周而复始的访问链表结点。

2.特点:
(1)没有任何结点数据域为NULL
(2)习惯于设置一个尾指针Tail,而不是设置一个头指针(原因:设置一个尾指针增删改查操作比较高效联想带头结点)
二、创建环状链表
提示:写代码一定要记得加注释,不然会扣分
//创建
ElemSN *CreateLink(int a[],int n){
//创建一个尾指针t
ElemSN *t=NULL;
//循环建表
for (int i = 0; i < n; i++){
ElemSN *p = (ElemSN*)malloc(sizeof(ElemSN));//创建结点
p->data=a[i];
if(!t){//当t为NULL
t = p->next=p;//让结点自己指向自己,再把尾结点指到结点上
}else{//当t不为NULL
p->next=t->next;//先将新结点p指到原来的结点上
t=t->next=p;//再把两个结点连接起来,把t挪到新的尾结点上
}
}
return t;//将尾结点返回到主调
}
//打印
void PrintLink(ElemSN *t){
ElemSN *p=t->next;
//因为使用了当型结构,结束条件也是开始条件,使得一个结点无法被访问,利用do while循环先执行后判断的特性
do{
printf("%5d",p->data);
p=p->next;
} while (t->next-p);
}
三、查找
设tail指向一个非空的单向环状链表,不重复,查找并返回关键字key的地址,若未找到,则返回NULL。
//查找
ElemSN *find(ElemSN *t ,int key){
ElemSN *p=t->next;
//利用do while循环查找key
do{
if(p->data==key){
return p;//如果找到key就返回指针p
}
p=p->next;
} while (t->next-p);
return NULL;//如果没找到就返回NULL
}
三、删除
设tail指向一个非空的单向环状链表,不重复,删除关键字key的地址。先查再删
//删除
ElemSN *Delete(ElemSN *t ,int key){
ElemSN *p=t->next,*delp;
int flag=0;//设置一个岗哨检查是否找到key
//利用do while循环查找key
do{//注意删除要用指针指向前驱结点
if(p->next->data==key){
flag=1;
break;
}
p=p->next;
} while (t-p);
if(flag){//找到key的结点,删除
delp=p->next;
p->next=delp->next;
if(delp==t){//如果待删结点是t指向的结点,需要再将新的尾结点p赋给t。
t=p;
}
free(delp);//释放key值所在的结点delp
}
return t;
}
思考题
判断一个非空单向链表如何带环。(下节实现)
3479

被折叠的 条评论
为什么被折叠?



