本文介绍循环双链表及C语言实现
循环双链表
双链表中,每个结点单元都有一个数据域和两个指针域,每个结点的pre指针指向上一个结点(若为头结点则指向NULL),每个结点的next指针指向下一个结点(若为尾节点则指向NULL)。
循环双链表与双链表大体差不多,只是在头结点和尾节点有所区别:
- 头结点的
pre指针指向尾结点 - 尾结点的
next指针指向头结点
因此,循环双链表的任何结点都不包含NULL
循环双链表的示意图如下:

循环双链表的结构体与双链表一样:
struct node
{
struct node *pre;
数据域;
struct node *next;
}
循环双链表的操作
插入
头结点插入
- 头结点为空
链表为空,直接进行初始化:
- 将新结点作为头结点
- 新结点的
pre指向头结点 - 新结点的
next指向头结点
操作如下:
head=ptr;
ptr->pre=head;
ptr->next=head;
- 头结点不为空
循环双链表的尾结点是指向头结点的,因此,要想在头结点插入的话必须先遍历到尾结点:
- 使用
temp=temp->next遍历到尾结点 - 使尾结点
temp的next指向新结点ptr - 使新结点的
pre指向尾结点temp - 使原头结点的
pre指向新结点ptr - 使新结点
ptr的next指向原头结点 - 将新结点作为头结点
示意图如下:

操作如下:
temp->next=ptr;
ptr->pre=temp;
head->pre=ptr;
ptr->next=head;
head=ptr;
尾结点插入
- 头结点为空的情况与在头结点插入为空的情况一致
- 头结点不为空
要在尾结点进行插入必须先遍历到尾结点,再进行插入操作:
- 使用
temp=temp->next遍历到尾结点 - 使新结点
ptr的pre指向原尾结点temp - 使头结点的
pre指向新结点ptr - 原尾结点
temp的next指向新结点ptr - 新结点
ptr的next指向头结点
实际上是将新结点作为新的尾结点的操作
示意图如下:

操作如下:
ptr->pre=temp;
head->pre=ptr;
temp->next=ptr;
ptr->next=head;
指定位置插入
指定位置的插入与双链表相同,这里对双链表的部分进行重述
- 先通过
temp=temp->next移动到指定位置,移动到该位置后结点后插入 - 使
ptr的下一指针指向temp的下一结点 - 使新结点
ptr的pre指向temp - 使
temp->next结点的pre指向新结点 - 使
temp的next指针指向ptr
示意图如下:

操作如下:
通过“temp=temp->next”移动到指定位置;//对应1
ptr->next=temp->next;//对应2
ptr->pre=temp;//对应3
temp->next->pre=ptr;//对应4
temp->next=ptr;//对应5
删除
头结点删除
- 只有一个结点
直接将仅有的头结点释放即可:
head=NULL;
free(head);
- 有多个结点
循环双链表的尾结点是指向头结点的,因此要删除头结点必须先遍历到尾结点
- 使用
temp=temp->next遍历到尾结点 - 将尾结点
temp的next指向头结点的下一个结点 - 让头结点下一结点的
pre指向尾结点temp - 将头结点的下一结点作为新的头结点
示意图如下:

操作如下:
ptr=head;
temp->next=head->next;
head->next->pre=temp;
head=head->next;
free(ptr);
尾结点删除
- 有一个结点时与只有一个结点在头部删除情况一致
- 有多个结点
循环双链表要删除尾结点应先遍历到尾节点
- 使用
ptr=ptr->next遍历到尾结点 - 让尾结点
ptr的前一结点的next指向头结点 - 让头结点的
pre指向尾结点ptr的前一结点 - 释放尾结点
ptr
示意图如下:

操作如下:
ptr->pre->next=head;
head->pre=ptr->pre;
free(ptr);
指定位置删除
指定位置的删除与双链表相同,这里对双链表的部分进行重述
- 先通过
temp=temp->next移动到指定位置,移动到该位置时删除该位置后的结点 - 检查该位置是否为最后一个结点,如果是的话将该结点的
next指针指向NULL - 若指定位置不是最后一个结点,则让
temp的next指针指向下一个ptr - 让
temp结点的next指向下一个ptr - 使
ptr结点的下一个结点的pre指向temp - 释放
ptr指针
示意图如下:

操作如下:
ptr->pre->next=ptr->next;
ptr->next->pre=ptr->pre;
free(ptr);
遍历
遍历时结点的next不为head就继续遍历
while(ptr->next!=head){
操作...
}
查找
将遍历到的数据与已有数据进行比对,有结点的数据相等则找到,否则数据不在链表里
while(ptr->next!=head){
结点的数据与现有数据比对...
}
循环双链表的C语言实现
本文提到的关于循环双链表的所有操作都使用C语言进行了实现,具体代码见Github
代码运行效果如下:

才疏学浅,难免有错误和不当之处,欢迎交流批评指正!
同时有问题的话欢迎留言或邮箱联系(ljt_IT@163.com)。

2427

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



