text: Floyd判圈演算法(Floyd Cycle Detection Algorithm)，又稱龜兔賽跑演算法(Tortoise and Hare Algorithm)，是一個可以在有限狀態機、迭代函式或者連結串列上判斷是否存在環，求出該環的起點與長度的演算法。該演算法據高德納稱由美國科學家羅伯特·弗洛伊德發明，但這一演算法並沒有出現在羅伯特·弗洛伊德公開發表的著作中。如果有限狀態機、迭代函式或者連結串列上存在環，那麼在某個環上以不同速度前進的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" := &amp;"S"2 "h" := &amp;"S" //令指標"t"和"h"均指向起點節點"S"。3 repeat4 "t" := "t"-&gt;next5 "h" := "h"-&gt;next6 if "h" is not NULL //要注意這一判斷一般不能省略7 "h" := "h"-&gt;next8 until "t" = "h" or "h" = NULL9 if "h" != NULL //如果存在環的話10 "n" := 011 repeat //求環的度12 "t" := "t"-&gt;next13 "n" := "n"+114 until "t" = "h"15 "t" := &amp;"S" //求環的一個起點16 while "t" != "h"17 "t" := "t"-&gt;next18 "h" := "h"-&gt;next19 "P" := *"t"演算法複雜度.時間複雜度.注意到當指標t到達環C的一個起點節點P時(此時指標h顯然在環C上)，之後指標t最多僅可能走1圈。若設節點S到P距離為formula_1，環C的長度為formula_2，則時間複雜度為formula_3，是線性時間的演算法。空間複雜度.僅需要創立指標t、指標h，儲存環長n、環的一個起點P。空間複雜度為formula_4，是常數空間的演算法。應用.對於有限狀態機與連結串列，可以判斷從某個起點開始是否會返回到訪問過執行過程中的某個狀態和節點。對於迭代函式，可以判斷其是否存在週期，以及求出其最小正週期。相關演算法.雖然Floyd判圈演算法已經達到了線性時間複雜度和常數空間複雜度，但是Brent判圈演算法將減小時間複雜度的常數係數，平均消耗時間比Floyd判圈演算法少36%。
metadata.dataset: erhwenkuo/wikipedia-zhtw
metadata.title: Floyd判圈演算法
metadata.url: https://zh.wikipedia.org/wiki?curid=4511013