使用两个指针判断一个单向链表是否存在环

使用两个指针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;
}

猜你喜欢

转载自blog.csdn.net/dongsongz/article/details/52673164