1. 程式人生 > >資料結構 - 如何找到有環單鏈表的環的入口位置(C++)

資料結構 - 如何找到有環單鏈表的環的入口位置(C++)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               
template<class T>Node<T> *SingleLinkedList<T>::getLoopEntrance(){ Node<T> *slow = head, *fast = head; while
(fast && fast->next) {  slow = slow->next;  fast = fast->next->next;  if (slow == fast)  {   break;  } } if (fast == NULL || fast->next == NULL) {  return NULL; } fast = head; while
(slow != fast) {  slow = slow->next;  fast = fast->next; } return fast;}

解法如下:

設定fast和slow兩個指標,初始都指向head。然後讓fast每次走2步,slow每次走一步,如果發現fast和slow重合,則確定單向連結串列有環路了。接下來,讓fast回到連結串列的頭部,重新走,每次步長不是走2步了,而是走1步,那麼當fast和slow再次相遇的結點,就是環路的入口位置了。

證明:
當fast和slow第一次相遇的時候,slow肯定沒有遍歷完一次連結串列或剛好遍歷完一次連結串列,而fast已經在環內迴圈了n圈(n>=1)。這時,假設slow走了i個結點,則fast走了2i個結點,再假設環長為C,則
  2i = i + nC -> i = NC

設連結串列長度為L,連結串列起點距環入口的距離為j,環入口距相遇點的距離為k,則

  j + k = i = nC

  j + k = (n - 1)C + C = (n - 1)C + (L - j)

  j = (n - 1)C + (L - j - k)

(L - j - k)同k一樣,同樣為環入口點距相遇點的距離。也就是說,從連結串列起點到環入口點的距離等於(n - 1)環長+相遇點到入口點的距離。於是,從連結串列起點、相遇點分別設一指標,每次各走一步,則兩指標必定相遇,且第一個相遇點即為環入口點。

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述