判斷乙個單鏈表是否有環及環的連線點

2021-07-11 16:20:47 字數 1996 閱讀 9218

給定乙個單鏈表,只給出頭指標h:

1、如何判斷是否存在環?

2、如何知道環的長度?

3、如何找出環的入口點在**?

4、帶環鍊錶的長度是多少?

解法:

1、對於問題1(判斷是否存在環),使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到null退出。

2、對於問題2(求環的長度),記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的運算元就是環的長度s,當然也可以利用slow再次走到p。

3、問題3(找出環的入口點):有定理:碰撞點p到連線點的距離=頭指標到連線點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。(證明在後面附註)。

4、問題3中已經求出連線點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度。

**如下

void isloop(node* head)

} if(!loop)

cout<<"this link has not loop\n";

elsewhile(p!=r);

while(p!=q)

cout<<"\nstart of loop: "問題3的證明

經過第1步確認存在環後,尋找環入口點:

演算法描述:

當fast若與slow相遇時,slow肯定沒有走遍歷完鍊錶,而fast已經在環內迴圈了n圈(1<=n)。

假設slow走了s步,則fast走了2s步(fast步數還等於s 加上在環上多轉的n圈),設環長為r,則:

2s = s + nr

s= nr

設整個鍊錶長l,環入口點

與相遇點距離為x,起點到環入口點的距離為a。則有l=a+r,l-a=r

a + x =s= nr

a + x = (n – 1)r +r = (n-1)r + l - a

a = (n-1)r + (l – a – x)

(l – a – x)為相遇點到環入口點的距離(即r - x 環的另一部分),由此可知,從煉表頭到環入口點等於(n-1)迴圈內環+相遇點到環入口點,於是我們從煉表頭、與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。(從碰撞點 x 前進 a 步即為連線點。)

鍊錶形狀類似數字 6 。

假設甩尾(在環外)長度為 a(結點個數),環內長度為 b 。

則總長度(也是總結點數)為 a+b 。

從頭開始,0 base 編號。

將第 i 步訪問的結點用 s(i) 表示。i = 0, 1 ...

當 i<a 時,s(i)=i ;

當 i≥a 時,s(i)=a+(i-a)%b 。

分析追趕過程:

兩個指標分別前進,假定經過 x 步後,碰撞。則有:s(x)=s(2x)

由環的週期性有:2x=tb+x 。得到 x=tb 。(x,t不是可以隨便變的變數,而是記號,分別記錄了slow走了多少步和fast比slow多走了幾圈)

另,碰撞時,必須在環內,不可能在甩尾段,有 x>=a 。

連線點為從起點走 a 步,即 s(a)。

s(a) = s(tb+a) = s(x+a)。(s(a) = s(tb+a) 和前面分析的s(x)=s(2x)無關,而是s(a) = s(nb+a),當n為任何數的時候都成立,當然為特定的t也是成立的)

得到結論:從碰撞點 x 前進 a 步即為連線點。

根據假設易知 s(a-1) 在甩尾段,s(a) 在環上,而 s(x+a) 必然在環上。所以可以發生碰撞。

綜上,從 x 點和從起點同步前進,第乙個碰撞點就是連線點。

判斷乙個單鏈表是否有環及環

判斷乙個單鏈表是否有環及環的鏈結點 蒙恩的罪人 給定乙個單鏈表,只給出頭指標h 1 如何判斷是否存在環?2 如何知道環的長度?3 如何找出環的連線點在 4 帶環鍊錶的長度是多少?解法 1 對於問題1,使用追趕的方法,設定兩個指標slow fast,從頭指標開始,每次分別前進1步 2步。如存在環,則兩...

判斷乙個單鏈表是否有環及環入口

要求 不允許修改鍊錶結構 時間複雜度o n 空間複雜度o 1 判斷是否有環 如果鍊錶有環,那麼在遍歷時則會陷入死迴圈。使用快慢指標 快指標移動2步,慢指標移動1步 如果走到某一步,快慢指標相遇,則說明有環 環入口點 我們假設鍊錶頭部到環入口距離 len,環入口到快慢指標交匯點的距離為x,環的長度為r...

判斷乙個單鏈表是否有環

一 判斷鍊錶是否存在環 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入 環,而slow後進入環,兩個指標必定相遇。當然,fast先行頭到尾部為null,則為無環鏈表 程式如下 bool i itsloop listn...