鍊錶有環的判斷

2021-10-02 03:39:59 字數 1498 閱讀 6819

今日一問:我們知道,在乙個煉表裡,如果某乙個節點的next屬性指向了鍊錶的另乙個節點,那麼這個鍊錶就是有環的。 那麼今天的問題是:如何判斷乙個單鏈表是有環的。乙個有環的鍊錶會給程式帶來什麼樣的隱患。

這個問題實際有固定的解答方式,就是使用快慢指標的方式。使用兩個指向煉表頭的引用,然後迴圈迭代,乙個指標每次往後移到一位,乙個指標每次往後移動兩位,那麼只會有兩種情況:

鍊錶無環,快指標移到next為空的地方;

鍊錶有環,連個指標必相遇;

第一種情況毫無疑問,對於第二種情況,慢指標總會移動到鍊錶的環上,然後快指標總會追上慢指標,且快指標每次走兩步,不會「越過」慢指標所以終會相遇。

public

class

test

if(i ==99)

} system.out.

println

(hasring

(list));

}private

static

boolean

hasring

(integernode list)

if(one == two)

}return result;

}}

如上是判斷鍊錶是否有環的**。

那麼知道鍊錶有環之後,還有如下需要計算:

哪乙個node是環的起始位置(也就是從鍊錶的頭部往後迭代,遇到的第乙個在環裡的node);

環的長度;

對於如上兩個問題,我們先記如下幾個值:

鍊錶的長度(也就是node的個數)為length;

不在環裡的node個數為a;

在環裡的node個數為b;

交匯點是環裡的第h個node;

那麼有如下等式:

2(a+h-1)=a+n*b+h-1

其中n是第一次相遇時,快指標所走的環的圈數。

可以得出:

a+h-1=n*b

也就是第一次相遇時,慢指標走的步數是環長的整數倍。

如果在他們相遇後,乙個指標從相遇點開始,乙個從鍊錶頭部開始,每次走一步,那麼當從煉表頭開始走的走到環的起始位置時,走了a-1步,另乙個指標也走a-1步,也就是nb-h步,二從環的第h位走nb-h正好也是走到環的起始位置,所以判斷環的啟示位置以及的方法如下:

//計算環的第乙個點

if(result)

system.out.

println

("環的第乙個點:"

+ one.

getvalue()

);int count =1;

two =

(integernode) two.next;

while

(one != two)

system.out.

println

("環的長度是"

+ count)

;}

至於鍊錶有環給程式帶來的隱患,就很簡單了,如果我們對列表做迴圈時沒有判斷這一點,那麼就會出現死迴圈。

如何判斷鍊錶是否有環 鍊錶是否有環的判斷

對於鍊錶是否存在環,有三個問題需要考慮 1.是否有環 2.入環節點 3.環的長度 第一種方法快慢指標法,也稱之為龜兔演算法,設定兩個指標,慢指標和快指標。最開始均指向鍊錶的頭節點,之後,快指標每次後移兩個節點,慢指標每次後移乙個節點。1.如果快指標指向空,則鍊錶無環 2.若快指標和慢指標再次指向乙個...

如何判斷鍊錶有環

假設存在環,環前共l個節點,環中共c個節點.設乙個慢指標起始位置為a,速度為1,快指標起始位置為b,速度為2.t時間後,二者相遇,可列方程 a t l mod c b 2 t l mod c 即t a b mod c 該模線性方程必定有解.所以無論a,b的起始位置如何,二者總是會相遇的.struct...

判斷鍊錶是否有環

1.如何判斷是否有環?如果有兩個頭結點指標,乙個走的快,乙個走的慢,那麼若干步以後,快的指標總會超過慢的指標一圈。2.如何計算環的長度?第一次相遇 超一圈 時開始計數,第二次相遇時停止計數。3.如何判斷環的入口點 碰撞點p到連線點的距離 頭指標到連線點的距離,因此,分別從碰撞點 頭指標開始走,相遇的...