判斷連結串列是否有環,求環的入口點及環長
今天的內容主要包括三部分,RT。
1。判斷連結串列是否帶環
判斷連結串列是否帶環,我們可以採用在頭結點設兩個指標,一個叫fast,一個叫slow,fast一下走兩步,而slow一下走一步。如果連結串列中存在環的話,那麼fast和slow必定會在環中相遇。若連結串列中沒有環的話,那麼fast必定現於slow指標先到達連結串列的尾節點(->next = Null)。我們現在來思考一個問題,為什麼連結串列中存在環,則slow和fast會在環中相遇?這個道理,我們可以聯想我們跑步追趕的例子,跑道是前面一段直行路,
後面是一個圓圈,當跑步選手進入環形跑道之後就只能在環形跑道里面繼續奔跑。有兩名選手在起點同時出發,那麼我們很容易明白跑得快的選手肯定會追趕上跑的慢的選手。哎,生活中都是學問啊,有木有???
2. 求環的入口點
老實說,求環的入口點有點複雜。我也是在看了一些前輩們的文章才比較清楚到底是怎麼一回事(http://www.cnblogs.com/youxin/p/3303172.html)。我們先看一幅圖,這幅圖也是我在程式中構造帶環連結串列的原型。
如上圖所示,12為帶環連結串列的入口點,簡單分析可知243是fast和slow的相遇點(鵲橋相會啊==!),a為環入口點到頭結點的路程,x為相遇點到環入口點的路程。我們假設slow指標走過的路程為s,那麼fast指標走過的路程則為2s,假設環長為c。且有
2s = s + nc
s = a + x
有上述式子,我們可以得到
a + x = nc
a = nc – x
a = (n – 1)c + c -x
式子化來化去,到這兒,我們是不是感覺有點不對經,好想如果在頭結點位置和相遇點位置分別再派出兩名跑步選手,並且他們都每次只跑一步,好像會在環的入口點相遇啊!!!恭喜你,答對啦!具體原因我們再分析分析最後一個式子就能明白了。啊。。。。求個環的入口點,我容易嘛我??
3.求環長
求環長就比較容易啦,沒用到什麼數學知識,對於數學知識捉急的我真是終於鬆了一口氣。就是再環的入口點設一指標和一計數器,讓這一指標在環裡面跑,計數器不斷自增。當這一指標回到環的入口點的時候,環長就出來啦!
4.完整程式碼請見:明天的任務是求兩連結串列是否相交,在連結串列存在有環的情況。繼續努力,機會只留給有準備的人!!!