对于循环单链表的结点,可以完全参照于单链表的结点设计,如图:
单向循环链表结点
data表示数据;
next表示指针,它总是指向自身的下一个结点,对于只有一个结点的存在,这个next指针则永远指向自身,对于一个链表的尾部结点,next永远指向开头。
其代码如下:
typedefstructlist{
intdata;
structlist*next;
}list;
//data为存储的数据,next指针为指向下一个结点
循环单链表初始化
先创建一个头结点并且给其开辟内存空间,在开辟内存空间成功之后,将头结点的next指向head自身,创建一个init函数来完成;
为了重复创建和插入,我们可以在init函数重新创建的结点next指向空,而在主函数调用创建之后,将head头结点的next指针指向自身。
这样的操作方式可以方便过后的创建单链表,直接利用多次调用的插入函数即可完成整体创建。
其代码如下:
//初始结点
list*initlist(){
list*head=(list*)malloc(sizeof(list));
if(head==NULL){
printf("创建失败,退出程序");
exit(0);
}else{
head->next=NULL;
returnhead;
}
}
在主函数中调用可以是这样
//////////初始化头结点//////////////
list*head=initlist();
head->next=head;
循环链表的创建操作
如图所示:
单向循环链表的创建
通过逐步的插入操作,创建一个新的节点,将原有链表尾结点的next指针修改指向到新的结点,新的结点的next指针再重新指向头部结点,然后逐步进行这样的插入操作,最终完成整个单项循环链表的创建。
其代码如下:
//创建——插入数据
intinsert_list(list*head){
intdata;//插入的数据类型
printf("请输入要插入的元素:");
scanf("%d",&data);
list*node=initlist();
node->data=data;
//初始化一个新的结点,准备进行链接
if(head!=NULL){
list*p=head;
//找到最后一个数据
while(p->next!=head){
p=p->next;
}
p->next=node;
node->next=head;
return1;
}else{
printf("头结点已无元素\n");
return0;
}
}
循环单链表的插入操作
如图,对于插入数据的操作,可以创建一个独立的结点,通过将需要插入的结点的上一个结点的next指针指向该节点,再由需要插入的结点的next指针指向下一个结点的方式完成插入操作。
其代码如下:
//插入元素
list*insert_list(list*head,intpos,intdata){
//三个参数分别是链表,位置,参数
list*node=initlist();//新建结点
list*p=head;//p表示新的链表
list*t;
t=p;
node->data=data;
if(head!=NULL){
for(inti=1;i<pos;i ){
t=t->next;//走到需要插入的位置处
}
node->next=t->next;
t->next=node;
returnp;
}
returnp;
}
循环单链表的删除操作
如下图所示,循环单链表的删除操作是先找到需要删除的结点,将其前一个结点的next指针直接指向删除结点的下一个结点即可。
需要注意的是尾结点,因为删除尾节点后,尾节点前一个结点就成了新的尾节点,这个新的尾节点需要指向的是头结点而不是空。