如何判斷循環鏈表


    實際上判斷一個鏈表是否是循環的思路很簡單,困擾我的反而是“帶環鏈表是否就是循環鏈表”這個問題,穿梭於各中帖子、書本尋找答案終究找不到明確說明。《大話數據結構》中循環鏈表的定義為:“將單鏈表中終端節點的指針端由空指針改為指向頭結點,就使整個單鏈表形成一個環,這種頭尾相接的單鏈表稱為單循環鏈表,簡稱循環鏈表。”也就是這個樣子的:



然后呢,還有其他帶環鏈表是這個樣子的:

暫時先把這兩種情況的鏈表都稱為循環鏈表吧(有些書籍就是這樣處理的),那么下面就進入主題:

判斷一個鏈表是否循環,那還不簡單!只要判斷有沒有指向NULL的指針就好了嘛,如果沒有指向NULL的指針,頭結點又重復出現,那可定就是循環鏈表了!代碼是這樣的:

看起來太簡單了是不是??如果說是,那么你就錯誤了。這種判斷方式只適合頭尾相接的循環鏈表,像“6”形的循環鏈表會導致程序進入死循環。那么,還有啥子辦法呢?當然是比較高大上的快慢指針啦:

     快慢指針的思想:定義兩個指向頭結點的指針pfast ,pslow,讓它們的步長不一樣,比如pfast步長2n,pslow步長為1n。然后,就讓它們同時從頭結點開始遍歷鏈表。如果鏈表是循環的,也即帶有環的,那么快慢指針總有再相遇的時候。就像操場跑步,操場是個環,跑的快的同學總會再遇上跑的慢的同學。

   那么,其實現方法是這樣的:

這種方法的時間復雜度是O(n),空間復雜度是O(1)。且不會修改原來的鏈表。倘若不要求O(1)的空間復雜度,還有其他的解法,比如:

解法二:

將所有的遍歷過的節點用某個結構存儲起來,然后每遍歷一個節點,都在這個結構中查找是否遍歷過,如果找到有重復,則說明該鏈表存在循環;如果直到遍歷結束,則說明鏈表不存在循環。這個結構我們可以使用hash來做,hash中存儲的值為節點的內存地址,這樣查找的操作所需時間為O(1),遍歷操作需要O(n),hash表的存儲空間需要額外的O(n)。所以整個算法的時間復雜度為O(n),空間復雜度為O(n)。

實際上還有其他很多方法,比如將原鏈表反向啊,構造雙向鏈表啊等等。不過個人還是覺得快慢指針最好用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM