如何判斷迴圈鍊錶
實際上判斷乙個鍊錶是否是迴圈的思路很簡單,困擾我的反而是「帶環鍊錶是否就是迴圈鍊錶」這個問題,穿梭於各中帖子、書本尋找答案終究找不到明確說明。《大話資料結構》中迴圈鍊錶的定義為:「將單鏈表中終端節點的指標端由空指標改為指向頭結點,就使整個單鏈表形成乙個環,這種頭尾相接的單鏈表稱為單迴圈鍊錶,簡稱迴圈鍊錶。」也就是這個樣子的:
然後呢,還有其他帶環鍊錶是這個樣子的:
暫時先把這兩種情況的鍊錶都稱為迴圈鍊錶吧(有些書籍就是這樣處理的),那麼下面就進入主題:
判斷乙個鍊錶是否迴圈,那還不簡單!只要判斷有沒有指向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)。
實際上還有其他很多方法,比如將原鍊錶反向啊,構造雙向鍊錶啊等等。不過個人還是覺得快慢指標最好用。
單向鍊錶判斷是否存在迴圈
本文由 lonelyrains 方法1 單鏈表判斷是否存在迴圈,即判斷是否有兩個指標指向同一位置,即判斷海量指標中是否有相同資料。然後對所有指標選擇插入排序或者快速排序。方法2 設定兩個指標互相追逐。乙個指標每次前進一步,第二個指標每次前進兩步,如果有相遇,則說明有環。1 方法1演算法效率不高,時間...
判斷鍊錶是否帶環
有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...
判斷鍊錶是否帶環
判斷鍊錶是否帶環 2009 08 28 16 18 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 ...