- 方法一:
- 通過快慢指針來檢查單連結清單是否存在循環
- 判斷是否是循環連結清單時,也設定兩個指針,慢指針和快指針,讓快指針比慢指針每次移動快兩次。如果快指針追趕上慢指針,則為循環連結清單,否則不是循環連結清單,如果快指針或者慢指針指向NULL,則不是循環連結清單。
- (1)用兩個指針p1和p2分别指向表頭結點,即p1=p2=head
- (2)p1和p2分别采用1和2作為步長周遊該連結清單。(注意,p2應該檢查目前結點的下一個結點是否為NULL)
- (3)如果p1或者p2遇到了NULL,則證明該連結清單沒有環;若p1和p2在某時刻指向同一結點,則說明該連結清單有環。
- 方法二:
- (a)p從表頭結點開始以1為步長周遊表,邊周遊邊将表反向
- (b)如果p遇到NULL,則說明表沒有環
- (c)如果p最後等于head,則說明表有環,且記此時p所經過的表的結點數為l(l=2l1+c,l1和c的定義見方法一)
- (d)p再從表頭結點開始以1為步長周遊表,邊周遊邊反向,當周遊到l/2時,停止,設兩個指針p1,p2均指向目前結點,然後分别從兩個方向同時以1為步長周遊表(其中一個需要邊周遊,邊反向連結清單),當他們第相遇時,目前結點即為環頭結點。且此時連結清單還原成原來的連結清單。
給定一個單連結清單,隻給出頭指針h:
1、如何判斷是否存在環?
2、如何知道環的長度?
3、如何找出環的連接配接點在哪裡?
4、帶環連結清單的長度是多少?
解法:
1、對于問題1,使用追趕的方法,設定兩個指針slow、fast,從頭指針開始,每次分别前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到NULL退出。
2、對于問題2,記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的操作數就是環的長度s。
3、問題3:有定理:碰撞點p到連接配接點的距離=頭指針到連接配接點的距離,是以,分别從碰撞點、頭指針開始走,相遇的那個點就是連接配接點。
4、問題3中已經求出連接配接點距離頭指針的長度,加上問題2中求出的環的長度,二者之和就是帶環單連結清單的長度。
判斷是否存在環的程式:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
尋找環連接配接點(入口點)的程式:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |