今天看到c專家程式設計的最後,有一處關於檢測鍊錶是否存在環的演算法介紹,這個問題和演算法之前在很多地方有看見,大致是有三個問題:1.給你乙個單向鍊錶判斷是否有環;2.求出環的長度;3.給出環的開始節點。演算法是這樣:讓兩個指標指向表頭,乙個每次移動一步,叫做慢指標,乙個每次移動兩步,叫做快指標,一直迴圈移動,如果最後兩者都碰到null指標則表示沒有環,如果最後兩者指向同乙個節點表示有環。至於問題2,3則是可以擴充套件得到,從快慢指標相遇的那個節點開始,令乙個新的指標開始遍歷,他從起點回到起點所經歷過的步數就是所求長度length,而環的開始節點可以這樣求,讓乙個指標p1指向煉表頭,另乙個p2指向離他length步的節點,p1,p2同時往前步步移動,他們相遇的節點既是環的起點。
問題2,3依賴問題1,且顯而易見,但是問題1的解法怎麼用準確的數學方法來證明,在存在環的情況下快指標一定會和慢指標相遇嗎?這裡有乙個比較好的證明:
證明過程大致如下:
鍊錶如上圖所述,pslow,pfast分別對應快慢指標,在指標在鍊錶上移動的時候有
pslow = x
pfast = 2(x+1)
當pslow到達m時pfast = 2(m+2), 這時候pslow與pfast都在環上移動,當pslow移動了t步後
pslow = m + t ==> m + t %n
pfast = 2*(m + t ) ==> m + (m + 2t)%n
現在,當且僅當m +t%n = m +(m+2t)%n 時 pslow = pfast,快慢指標相遇,解這個等式:
m +t%n = m +(m+2t)%n ==> t%n = (m+2t)%n ==> (m+t)%n = 0
m是非負整數,n是正整數,t是正整數,顯然對於任意的m,n必然存在乙個t使得等式成立。
演算法 檢測是否鍊錶存在環
這兒例子使用快慢指標的辦法實現。h lengthx e m e m lengthy m e lengthz length of circle lengthy lengthz 假定1.開始點是h,環的進入點是e,快指標和慢指標首次相遇的點是m.2.慢指標和快指標首次相遇在m點的時候,是慢指標首次到達m...
鍊錶是否存在環
鍊錶環的問題有兩種,一種是判斷是否存在環,另一種是在有的基礎上返回入環的第乙個節點。簡單思路 1 遍歷鍊錶,如果遇到空,那麼肯定無環。2 在遍歷的過程中,每個節點都加入到雜湊表中,加入前判斷是否存在,如果存在的話那麼就有環,而且第乙個判斷存在的節點就是入環的第乙個節點。總結 這個比較簡單,既可以做到...
鍊錶 檢測是否有環
typedef struct node node,lnode 單鏈表bool isloop lnode ln return true 檢測兩個鍊錶是否相交 一種方法 首尾相交,如果有環則相交 否則不相交。node gettailnode lnode ln if null ln return null...