使用兩個指針判斷一個單向鏈表是否存在環

使用兩個指針pfast, pslow從頭節點開始,依次向後走,pfast一次兩步,pslow一次一步,當兩個指針相等,則存在環,否則不存在。


當pfast與pslow相遇的時候,pfast經過的環形路程比pslow經過的環形路程一定多了環長的整數倍。從起點走到連接點與pfast和pslow相遇的點繼續走到連接點的距離相等。

假設從起點到連接點走a步到連接點,記爲S(a),設pslow走x步與pfast相遇,則有S(2x) =  2S(x),即2 x = x + n b;b爲環的長度,可得x = nb

則S(x +a) =  S(a+nb)因此,從起點和相遇點一次一步會相遇在連接點。 


找到連接點,則環的長度及鏈表總長度都迎刃而解。


typedef struct node{
    struct node *next;
}Node, *Pnode;

Pnode find_circle(Pnode head)
{
    Pnode pfast,pslow;
    if(head == NULL)
        return NULL;
    pfast = head;
    pslow = head;
    while(pfast && pfast->next){
        pfast = pfast->next->next;
        pslow = pslow->next;
        if(pfast == pslow)      //兩個指針相遇
            return pfast;
    }
    return NULL;
}

Pnode find_entrance(Pnode head, Pnode pmeet)
{
    if(head == NULL || pmeet == NULL)
        return NULL;
    while(head){
        if(head == pmeet)       //相遇爲連接點,即入口點
            return pmeet;
        head = head->next;
        pmeet = pmeet->next;
    }

    return NULL;
}

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