查看“︁Floyd判圈算法”︁的源代码
←
Floyd判圈算法
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
'''Floyd判圈算法'''('''Floyd Cycle Detection Algorithm'''),又称'''龟兔赛跑算法'''('''Tortoise and Hare Algorithm'''),是一个可以在[[有限状态机]]、[[迭代函数]]或者[[链表]]上判断是否存在[[環 (圖論)|环]],求出该环的起点与长度的算法。该算法据[[高德纳]]称由美国科学家[[罗伯特·弗洛伊德]]发明,但这一算法并没有出现在[[罗伯特·弗洛伊德]]公开发表的著作中[https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare]{{Wayback|url=https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare |date=20150215031856 }}。 如果有限状态机、迭代函数或者链表上存在环,那么在某个环上以不同速度前进的2个[[指針 (信息學)|指针]]必定会在某个时刻相遇。同时显然地,如果从同一个起点(即使这个起点不在某个环上)同时开始以不同速度前进的2个指针最终相遇,那么可以判定存在一个环,且可以求出2者相遇处所在的环的起点与长度。 == 算法 == === 算法描述 === 如果有限状态机、迭代函数或者链表存在环,那么一定存在一个起点可以到达某个环的某处(这个起点也可以在某个环上)。 初始状态下,假设已知某个起点[[节点]]为节点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的一个起点。 === 伪代码 === 1 ''t'' := '''&'''''S'' 2 ''h'' := '''&'''''S'' //令指針''t''和''h''均指向起點節點''S''。 3 '''repeat''' 4 ''t'' := ''t''->next 5 ''h'' := ''h''->next 6 '''if''' ''h'' is not NULL //要注意這一判斷一般不能省略 7 ''h'' := ''h''->next 8 '''until''' ''t'' = ''h'' '''or''' ''h'' = NULL 9 '''if''' ''h'' != NULL //如果存在環的話 10 ''n'' := 0 11 '''repeat''' //求環的度 12 ''t'' := ''t''->next 13 ''n'' := ''n''+1 14 '''until''' ''t'' = ''h'' 15 ''t'' := '''&'''''S'' //求環的一個起點 16 '''while''' ''t'' != ''h'' 17 ''t'' := ''t''->next 18 ''h'' := ''h''->next 19 ''P'' := '''*'''''t'' ===算法复杂度=== ====时间复杂度==== 注意到当指针t到达环C的一个起点节点P时(此时指针h显然在环C上),之后指针t最多仅可能走1圈。若设节点S到P距离为<math>m</math>,环C的长度为<math>n</math>,则时间复杂度为<math>O(m+n)</math>,是[[线性]]时间的算法。[https://web.archive.org/web/20160313063357/http://www.siafoo.net/algorithm/10] ====空间复杂度==== 仅需要创立指针t、指针h,保存环长n、环的一个起点P。空间复杂度为<math>O(1)</math>,是[[常数]]空间的算法。[https://web.archive.org/web/20160313063357/http://www.siafoo.net/algorithm/10] ==应用== 对于有限状态机与链表,可以判断从某个起点开始是否会返回到访问过运行过程中的某个[[状态]]和节点。 对于迭代函数,可以判断其是否存在[[周期]],以及求出其[[最小正周期]]。 ==相关算法== 虽然Floyd判圈算法已经达到了线性时间复杂度和常数空间复杂度,但是[[Brent判圈算法]]将减小时间复杂度的常数系数,平均消耗时间比Floyd判圈算法少36%。[https://web.archive.org/web/20160304043822/http://www.siafoo.net/algorithm/11] == 参考链接 == *[https://web.archive.org/web/20160313063357/http://www.siafoo.net/algorithm/10 Floyd's Cycle Detection Algorithm (The Tortoise and the Hare)] *[https://web.archive.org/web/20160304043822/http://www.siafoo.net/algorithm/11 Brent's Cycle Detection Algorithm (The Teleporting Turtle)] *[https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare Floyd's cycle-finding algorithm]{{Wayback|url=https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare |date=20150215031856 }} [[Category:图论算法]]
该页面使用的模板:
Template:Wayback
(
查看源代码
)
返回
Floyd判圈算法
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息