![数据结构(C语言实现)](https://wfqqreader-1252317822.image.myqcloud.com/cover/699/43806699/b_43806699.jpg)
2.3.4 循环单链表
1.循环单链表的存储
循环单链表(Circular Linked List)是一种首尾相连的单链表。在线性链表中,每个结点的指针都指向它的下一个结点,最后一个结点的指针域为空,不指向任何结点,仅表示链表结束。若把这种结构改变一下,使最后一个结点的指针域指向链表的第一个结点,就构成了循环链表。
与单链表类似,循环单链表也可分为带头结点的结构和不带头结点的结构。循环单链表不为空时,最后一个结点的指针域指向头结点。如图2.22所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/47_02.jpg?sign=1739531226-sZ1i9rkJBt53C3SBmZ8QHrXfufr0io23-0-26cdd5fe401ad6078cc7842bb8f894ba)
图2.22 带头结点的循环单链表
循环单链表为空时,头结点的指针域指向头结点本身。如图2.23所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/47_03.jpg?sign=1739531226-tzz7sSdEdMSSQQPzCUxVqcO9yVo6VMbj-0-baab904c813c916a3718495708267423)
图2.23 循环单链表为空时的情况
注意:带头结点的循环单键表为空时,有head->next==head。
有时为了操作上的方便,在循环单链表中只设置尾指针rear而不设置头指针,利用rear指向循环单链表的最后一个结点。如图2.24所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/47_04.jpg?sign=1739531226-E5OHkhPjFgFHeNBEOuN0eHXjFnHOW2Ik-0-f1f0151f0259fd188883afb7b6a7298a)
图2.24 只设置尾指针的循环单链表示意图
利用尾指针可以使有些操作变得简单,例如,要将如图2.25所示的两个循环单链表(尾指针分别为LA和LB)合并成一个链表,只需要将一个表的表尾和另一个表的表头连接即可。如图2.26所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/47_05.jpg?sign=1739531226-p5VTA3xQZc4XsotO8KEP6n5ocuiwzCCG-0-aeb5321e4a1a074ca8ba5d56dae229b1)
图2.25 设置尾指针的循环单链表LA和LB
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/48_01.jpg?sign=1739531226-H0WardhcQjWNlWUjiKP1tdYvt6nbuZ1B-0-920c2338df930fc1e2945f9bcac8e496)
图2.26 两个设置尾指针的循环单链表合并后的示意图
合并两个设置尾指针的循环单链表需要三步操作:
①把LA的表尾与LB的第一个结点相连接,即LA->next=LB->next->next。
②释放LB的头结点,即free(LB->next)。
③把LB的表尾与LA的表头相连接,即LB->next=LA->next。
2.循环单链表的应用
【例2.4】 约瑟夫问题。有n个人,编号为1,2,…,n,围成一个圆圈,按照顺时针方向让编号为k的人从1开始报数,报数为m的人出列,从出列的下一个人重新开始报数,报数为m的人出列,一直这样重复下去,直到所有的人都出列。要求编写一个算法,输入n、k和m,依次输出每次出列人的编号。
【分析】解决约瑟夫问题可以分为三个步骤:
(1)建立一个具有n个结点的不带头结点的循环单链表,编号从1到n,代表n个人。
(2)找到第k个结点,即第一个开始报数的人。
(3)编号为k的人从1开始报数,并开始计数,报数为m的人出列即删除该结点。从下一个结点开始继续报数,重复执行步骤(2)和(3),直到最后一个结点被删除。
约瑟夫问题算法描述如下:
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/48_02.jpg?sign=1739531226-H7O0gRjEWA0HbCQejns4ufvbF8r9vkaG-0-2ddb20d0a5d4671c980caa0e2dba2c5e)
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/49_01.jpg?sign=1739531226-MZmPPU1lFfMz0X7IScnKM95jNmSWV5EX-0-4b536c6259b57e94b2a2c295a8fe07ed)
测试程序如下:
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/49_02.jpg?sign=1739531226-J1MpHGRKurplRcbfaSTMqiY3sBOOkYDv-0-f48d3e473b1a3b934d0d2dc7cd94bcdf)
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/50_01.jpg?sign=1739531226-Dcu0LIF8ClbaUzi9lT9pE4C75lja0Jbw-0-12cdd3ba999e8b13c1abedc8afc5d9fe)
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/50_02.jpg?sign=1739531226-15dXT08nFyU27QXW4rPkqmIcSbZsOU20-0-f4eb456dc964b597753d962d1eb42a85)
图2.27 程序运行结果
程序运行结果如图2.27所示。