如何判斷一個鏈表是否有環?以及對一些文章的錯誤的見解

以前同窗跟我討論如何判斷一個鏈表是否有環,以及如何得知環的入口點,說是Programming Pearls (編程珠璣)上面的習題。html

如下是個人理解,以及認爲大部分文章中關於「定理:碰撞點p到鏈接點的距離=頭指針到鏈接點的距離」 並不正確,討論見文末。算法

 

           圖片來源編程

當時我想哈希的方式處理,不過這個方法知識理論可行,實際不具備操做性。spa

後面上網查了資料,問題的解法很巧妙。用速度爲1和2的兩個指針遍歷鏈表,若是有環的話,這兩個指針就會碰撞。bingo, 問題解決。.net

經過相似的思路,能夠簡單的計算環的長度,即在碰撞點繼續前進,當他們再次相遇時,快的指針比慢的指針恰好多走一圈,也就是環的長度。指針

這道題讓我想到了小學時候的數學題,一個跑得快的人和一個跑得慢的人,他們多久後相遇。htm

尋找環的入口點方法是從頭指針、碰撞點以同樣的速度出發(注意不是1和2了),相遇的地方就是環的入口點。很簡單很巧妙,可是這個證實這樣作爲何會對。blog

 

我看了網上的資料,大部分給了算法,而後看了一篇證實,以爲思路不夠簡單明瞭。因而我本身想出了以下的方法,用來理解。圖片

首先很容易獲得以下的等式,看符號解釋便可明白,由於快的指針走的距離是慢的指針的2倍。get

$$2(L_{HE} + d) = L_{HE} + kL + d$$

其中$L_{HE}$,爲頭指針到入口處的距離

$L$ 爲環的長度

$d$是入口處到它們相遇的地放的距離

$k$爲天然數,快的指針在與慢指針碰撞時走的圈數

經過上式可得 爲$L_{HE}  = kL -d $, 有了這個等式,咱們能夠進行以下簡單明瞭的理解了:

速度同樣的兩個指針,假設指針Head從頭指針出發,指針Entry從碰撞點出發,當它們相遇時,Entry走過的路程爲$kL - d$,指針Head的距離$L_{HE} $。這不明顯相等嗎?一個等式,化簡一下就出來了,稍微理解一下就能夠了。

 

還有一個提醒是,當快慢指針相遇時,慢指針沒有走完環。這個稍微一想,或者列個式子就能夠明白了。

 參考文章  (「問題3:有定理:碰撞點p到鏈接點的距離=頭指針到鏈接點的距離,」不少文章都這麼寫,可是我的認爲這個等式不成立,由於它們會在鏈接點相遇不等於它們到鏈接點的距離相等。舉個例子,環長度爲2,頭指針到環的入口處爲10,顯然等式不成立。真正成立的等式,讀者本身能夠動手列一下。

原文首發於博客園 Hall Of FAME

地址

相關文章
相關標籤/搜索