《C專家程式設計》:如何檢測連結串列裡的環(附1)

塵虛緣_KY發表於2016-06-19
題目:怎樣才能檢測到連結串列中存在環。
沒有任何條件限制:

方案:使用標記法:將訪問過的元素進行標記(通過修改連結串列的結構),如果遍歷玩連結串列還沒有碰見標記的元素,則說明沒有環,反之則有;O(N)時間複雜度。
資料位於只讀儲存區,不能修改:
方案:空間換時間:申請一個N個元素大小的記憶體空間,用雜湊表將所有的元素儲存起來,看後面的元素有沒有重複的,若有,則存在環;沒有則不存在。時間複雜度為O(N),空間複雜度為O(N)。
沒有足夠的空間:
方案一:
使用兩個指標,第一個指標指向第一個資料,第二個指標依次遍歷後面的資料,如果沒有;則第一個指標向後移一個,第二個指標再從第三個元素一次向後查詢遍歷....看是否有相等的資料,若有,則存在環;否則,不存在環。但是此種演算法效率實在低下,O(N*N),泛善可陳,丟掉吧。

方案二(推薦):還是設定兩個指標。由於連結串列的長度是任意的,所以先看一種特殊的情況:就是有三個元素,其實只有兩個值,第二個元素的下一個就是第一個元素。如果不存在則進行下一步判斷,第一個指標走一步,第二個指標走兩步,這樣如果立案表裡有環,則這兩個指標將深陷此環而永不復出,那麼一個走一步,另一個走兩步,總有一天會相遇,如果存在值相等,則說明有環,否則如果有一個指標走到了連結串列的盡頭,等於NULL,則說明連結串列中五環。時間複雜度為O(N),空間複雜度為0。詳細圖如下:


     但是這些方案也有侷限性,前提是連結串列裡沒有重複資料,否則不好使,將會把重複的資料判斷是有環存在。
     所以如果該連結串列可以修改我們可以採取標記法來判斷就可以處理重複的資料了!時間複雜度O(N)。
     如果不能修改但是可以申請空間,那麼我們就可以用雜湊表的結構照樣採用標記法來判斷是否有環。時間複雜度為O(N)。
     如果既不能修改也不能申請空間,除了設定兩個指標以外,我想我們可以比較地址,但是效率較低O(N*N)!

相關文章