本博文介绍循环单链表及其C语言的实现
循环单链表
单链表中,链表的最后一个结点的指针为NULL
,每次遍历单链表都需要从头结点开始访问。
不同于单链表,循环单链表的示意图如下所示,循环单链表的尾结点的指针不为空,其指向了头结点,这样一来每次遍历单链表就不一定非得从头结点开始,从任意结点都可以遍历整个循环单链表。
循环单链表的结构体和单链表的结构体一样:
struct node
{
数据域;
struct node *next;
}
循环单链表的操作
插入
头结点插入
- 链表为空
链表为空时直接插入以进行初始化:
head=ptr;
ptr->next=head;
- 链表非空
循环单链表尾结点的next
是指向头结点的,因此要从头结点进行插入的话必须先遍历到尾结点:
- 通过
temp=temp->next
移动到尾结点 - 让新结点
ptr
的next
指向头结点 - 让尾结点
temp
的next
指向新结点ptr - 将新结点
ptr
作为头结点
示意图如下:
操作如下:
ptr->next=head;
temp->next=ptr;
head=ptr;
尾结点插入
- 链表为空时的插入操作与头结点的插入操作相同
- 链表不为空
应先遍历到链表的尾结点,然后进行插入操作:
- 使用
temp=temp->next
遍历到尾结点 - 使尾结点
temp
的next
指向新结点ptr
- 使新结点
ptr
的next
结点指向头结点
示意图如下:
操作如下:
temp->next=ptr;
ptr->next=head;
指定位置插入
此部分与单链表的操作一致,以下为重述单链表部分的操作
- 应先通过
temp=temp->next
先移动到指定位置 - 使新结点
ptr
的next
指向temp
的下一部分地址 temp
的next
指向新结点ptr
即可
示意图如下:
操作如下:
ptr->next=temp->next;
temp->next=ptr;
删除
头结点删除
- 只有头结点
直接释放头结点:
head=NULL;
free(head);
- 有多个结点
循环单链表的尾结点的next
是指向头结点的,因此应先遍历的尾结点再进行头结点的删除操作
- 使用
temp=temp->next
遍历到尾结点 - 使尾结点
temp
的next
指向头结点的下一结点 - 头结点移动到原头结点的下一结点
示意图如下:
操作如下:
ptr=head;
temp->next=head->next;
head=head->next;
free(ptr);
尾结点删除
- 只有头结点的操作与头结点删除的情况相同
- 有多个结点
循环单链表的尾结点的next
是指向头结点的,要删除尾结点,应使尾结点的上一结点的next
指向头结点,因此需要两个指针:
- 使用
temp
和ptr
进行遍历链表,使ptr
成为尾结点,temp
为尾结点的上一结点 - 让
temp
的next
指向头结点 - 释放尾结点
ptr
示意图如下:
操作如下:
ptr=head;
while(ptr->next!=head){
temp=ptr;
ptr=ptr->next;
}
temp->next=head;
free(ptr);
指定位置删除
此部分与单链表的操作一致,以下为重述单链表部分的操作
- 由于为单链表,若指定位置为的结点为
ptr
,想删除ptr
的话必须得对ptr
上一位置进行操作,因此使用两个指针:p
和ptr
- 通过
ptr=ptr->next
移动到指定位置 - 使指定位置的上一位置的指针p指向指定位置的下一位置
- 释放指定位置指针
ptr
示意图如下:
操作如下:
移动指定步{
p=ptr;
ptr=ptr->next;
}
p->next=ptr->next;
free(ptr);
遍历
只要遍历到结点的next
不为head
就继续遍历:
while(ptr->next!=head){
操作...
}
查找
在遍历到的数据进行比对以访问查找数据:
while(ptr->next!=head){
比对操作...
}
循环单链表的C语言实现
以上所提到的所有操作都使用C语言进行了实现,具体代码见Github
代码的实现效果如图所示:
才疏学浅,难免有错误和不当之处,欢迎交流批评指正!
同时有问题的话欢迎留言或邮箱联系(ljt_IT@163.com)。