判斷一個單鏈表是否有環及環的鏈接點

一種方法是設置兩個指針指向單鏈表的head, 然後開始遍歷,第一個指針走一步,第二個指針走兩步,如果沒有環,它們會直接走到底,如果有環,這兩個指針一定會相遇。該方法的實現代碼如下,程序中找出了環的起始位置:

node* first_loop_port(node *head)
{
    node *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;
    slow = head;
    while (slow != fast)
    {
         slow = slow->next;
         fast = fast->next;
    }
    return slow;
}

證明:

假設單鏈表的總長度爲L,頭結點到環入口的距離爲a,環入口到快慢指針相遇的結點距離爲x,環的長度爲r,慢指針總共走了s步,則快指針走了2s步。另外,快指針要追上慢指針的話快指針至少要在環裏面轉了一圈多(假設轉了n圈加x的距離),得到以下關係:
    s = a + x;
    2s = a + nr + x;
    =>a + x = nr;
    =>a = nr - x;
    由上式可知:若在頭結點和相遇結點分別設一指針,同步(單步)前進,則最後一定相遇在環入口結點,搞掂!
附圖:

帶環的鏈表


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章