口试之-判断单链表是否有环

面试之------判断单链表是否有环
某次面试中第一道题目,但是结果没思路。
单链表的每个节点都单向指向下一个节点,所以如果有环则只可能是链表尾指向了前面的某个节点(可能是头节点或者任意)。

下面是算法实现:

bool is_loopList(listNode *head)
{
    listNode *p1 = *p2 = head;
    //边界判断
    if(null == head || null == head->next)
    {
        return false;
    }
    /**
    1--设定两个指针,一个单步走,一个两步走。
    2--如果无环,则快指针会很快走到链表尾;如果有环则不会走到链表尾,但是两个指针会相遇。
    */
    while(null != p2->next && null != p2->next->next)
    {
        p1 = p1->next;
        p2 = p2->next->next;
        if(p1 == p2)
        {
            return true;
        }
    }
    return false;
}


扩展一下的话,可以求出环的大小,算法实现如下:

/*
有环单向链表中大小指针会多次相遇;而且两次相遇之间的差值就是环的大小
*/
int get_size_of_linkedlist_loop(linkedList *head){
    int loop_size;
    linkedList *p1 = head, *p2 = head;
    bool hasMeet = false;
    while(!secondMeet){
        ++loop_size;
        p1 = p1->next;
        p2 = p2->next->next;
        if(!hasMeet && p1 == p2){
        hasMeet = true;
        loop_size = 0;
        }
        if(hasMeet && p1 == p2)
        break;
    }
    return loop_size;
}