給定一個單鏈表,只給出頭指標h:
1、如何判斷是否存在環?
2、如何知道環的長度?
3、如何找出環的連接點在哪裡?
4、帶環鏈表的長度是多少?
解法:
1、對於問題1,使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到NULL退出。
2、對於問題2,記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的運算元就是環的長度s。
3、問題3:有定理:碰撞點p到連接點的距離=頭指標到連接點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連接點。
該定理的證明可參考:http://fayaa.com/tiku/view/7/
4、問題3中已經求出連接點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度
判斷是否存在環的程式:
bool IsExitsLoop(slist *head)<br />{<br /> slist *slow = head, *fast = head;</p><p> while ( fast && fast->next )<br /> {<br /> slow = slow->next;<br /> fast = fast->next->next;<br /> if ( slow == fast ) break;<br /> }</p><p> return !(fast == NULL || fast->next == NULL);<br />}
尋找環連接點(進入點)的程式:
slist* FindLoopPort(slist *head)<br />{<br /> slist *slow = head, *fast = head;</p><p> while ( fast && fast->next )<br /> {<br /> slow = slow->next;<br /> fast = fast->next->next;<br /> if ( slow == fast ) break;<br /> }</p><p> if (fast == NULL || fast->next == NULL)<br /> return NULL;</p><p> slow = head;<br /> while (slow != fast)<br /> {<br /> slow = slow->next;<br /> fast = fast->next;<br /> }</p><p> return slow;<br />}