如何判斷迴圈鍊錶

2022-01-21 22:38:28 字數 1245 閱讀 7692

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

然後呢,還有其他帶環鍊錶是這個樣子的:

暫時先把這兩種情況的鍊錶都稱為迴圈鍊錶吧(有些書籍就是這樣處理的),那麼下面就進入主題:

判斷乙個鍊錶是否迴圈,那還不簡單!只要判斷有沒有指向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演算法效率不高,時間...

《演算法之美》 鍊錶問題 判斷鍊錶迴圈與否

問題 乙個鍊錶要麼以null結尾 非迴圈的 要麼以迴圈結尾 迴圈的 請編寫乙個函式,接受鍊錶的頭指標作為引數,確定該鍊錶是迴圈的還是非迴圈的。如果鍊錶是迴圈的,函式返回true,如果是非迴圈的,函式返回false。注意,不能以任何方式修改鍊錶。解答 這兩種鍊錶的區別在與它們的末尾。在非迴圈鍊錶中,末...