Floyd判圈算法

Floyd判圈算法

wiki 的介绍

以下是引用 wiki 的介绍:
Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,求出该环的起点与长度的算法。

如果有限状态机、迭代函数或者链表存在环,那么一定存在一个起点可以到达某个环的某处(这个起点也可以在某个环上)。

初始状态下,假设已知某个起点节点为节点S。现设两个指针t和h,将它们均指向S。

接着,同时让t和h往前推进,但是二者的速度不同:t每前进1步,h前进2步。只要二者都可以前进而且没有相遇,就如此保持二者的推进。当h无法前进,即到达某个没有后继的节点时,就可以确定从S出发不会遇到环。反之当t与h再次相遇时,就可以确定从S出发一定会进入某个环,设其为环C。

如果确定了存在某个环,就可以求此环的起点与长度。

上述算法刚判断出存在环C时,显然t和h位于同一节点,设其为节点M。显然,仅需令h不动,而t不断推进,最终又会返回节点M,统计这一次t推进的步数,显然这就是环C的长度。

为了求出环C的起点,只要令h仍均位于节点M,而令t返回起点节点S,此时h与t之间距为环C长度的整数倍。随后,同时让t和h往前推进,且保持二者的速度相同:t每前进1步,h前进1步。持续该过程直至t与h再一次相遇,设此次相遇时位于同一节点P,则节点P即为从节点S出发所到达的环C的第一个节点,即环C的一个起点。

个人理解

判断是否有环

放一个快指针fast与慢指针slow在链表头部,快指针每次移动两步,慢指针移动一步。如此移动下去只会有两个结果:

  • 快指针走到链表尾部。即不存在环

    在这里插入图片描述

    【图1】

  • 快慢指针在环内相遇。即存在环

    在这里插入图片描述

    【图2】

求入环节点

那么如何上面已知环存在的基础上,求环的入口节点呢?

在这里插入图片描述

【图3】

一些数学推导(参考网上)

假设,环外长 a a a,环长为 L = b + c L=b+c L=b+c ,当slow刚进入环时,fast指针位于环内的 x x x点处,距离环入口长度 b b b 见【图3】。则fast追上slow的距离为 d = L − b d=L-b d=Lb

已知:

  • slow指针速度为 1/s;fast指针速度为 2/s 。因此fastslow的相对移动速度为1/s,即每周期距离缩短一个单位,所以两指针相交共需要 L − b 1 / s \frac{L-b}{1/s} 1/sLb个移动周期
  • 由于slow每周期移动一个单位,所以与fast相遇时slow需要在环内移动 L − b L-b Lb个单位,也就是说,在入环口处慢>指针再走 L − b L-b Lb个单位就可到达相交点
  • 观察 d d d取最大值的情况,即当 b = 0 b=0 b=0时,此时slow刚到环的入口就与fast相交,因此环内的追击距离为 0 0 0
  • 其他
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值