本文介绍循环双链表及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)。