1. 程式人生 > >【資料結構】環形連結串列

【資料結構】環形連結串列

給定一個連結串列,判斷連結串列中是否有環。

  • 思路分析:

判斷連結串列是否帶環,實際上歸屬於快慢指標問題,快指標先進環,慢指標後進環,然後快指標和慢指標最終會在環裡面相遇,如果不會相遇,則表示不是迴圈連結串列,也就是說到頭了,即不帶環。

  • 具體程式碼如下:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=slow;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }
    return false;
}
  • 補充問題:

請證明,為什麼是slow指標走一步,fast指標走兩步,slow指標走一步,fast指標走三步行嗎?四步呢?

有兩種證明方法:

①反證法

假如slow指標走1步,fast指標走3步,也就是說他們兩每走一次,距離縮小2,那麼一直縮小:n-2,n-4,n-6,,......3,當縮小為1步時,如果再縮小一步,他們兩就剛好會錯開,而當環的程度剛好到達某個特殊點的時候,每次準備相遇是,就錯開,一直這樣,就會永遠錯開,舉個例子來說明:

②直接證明:

假設fast指標和slow指標相差n步,fast指標走兩步,slow指標走一步,意味著他們兩每走一次,距離縮小1,那麼一直縮小:n-1,n-2,n-3,,......2,1,最後一定會縮小到0步,也就是說最終肯定會相遇。