消除链表中的循环

本文介绍了在检测到链表存在循环后,如何找到循环尾部并消除循环的方法。通过使用快慢指针,当它们相遇时,将快指针移动回链表头部,然后两个指针同步移动,再次相遇的位置即为循环头部。接着,保持快指针不变,慢指针继续移动,当慢指针的next指向快指针时,找到循环尾部,将其next设为NULL即可消除循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上篇文章--"检测链表中是否存在循环"(http://blog.youkuaiyun.com/iccav/article/details/11682089)中介绍了如何检测链表中的循环,这篇文章介绍一下如果消除循环。

图片来自(http://www.crazyforcode.com/write-program-detect-loop-linked-list/)

问题描述:

假设我们有一个链表,链表中存在循环,我们如何消除循环?即如何找到链表的尾部(在本图中是5),并将循环尾部的next指针设为NULL。

思路:

先推导一个我们要用到的结论。

假设链表中直链部分的长度为m(链表中的非循环部分,在本图中是2),链表中循环部分的长度为n(在本图中是3)。同样是用两个指针,一个fast,一个slow。由于两个指针都是从头部开始移动的,fast指针的移动速度是slow移动速度的两倍,故若存在循环,则当两个指针相遇时,fast指针的移动的长度应该是slow指针移动长度的两倍。假设slow的移动长度为length,则fast指针移动的长度是2*length。假设fast和slow相遇时,距离循环头部的长度为k(在本图中循环的头部是指3号节点)则有如下等式:

leng = m + p*n + k 其中p是指在两指针相遇之前,slow指针已经在循环中走完了p次

2*length = m + q*n + k 其中q是指在两指针相遇之前,fast指针已经在循环中走完了q次

消去length,得到等式

m  = (q-2p)*n - k

现在如果我们将fast指针定位到链表的头部,slow此时仍然在fast和slow相遇的位置,将fast和slow指针同时向右移动,每次都移动一步。当fast移动了m步时,由于fast此次是从链表的头部开始

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值