数据结构| |链表的面试题之判断单链表是否带环,求环长度以及求环的入口点

对于头文件这里就不在写了,直接写思路以及代码实现!
头文件可以参考前面的博客。地址:https://blog.csdn.net/qq_40399012/article/details/81742603

对于一个单链表其带环是一个什么样子的呢?就是下面的样子。
带环的单链表

对于带环的单链表可以准确到看到其没有尾结点!最后指针会在这个环里面一直走呀走!

判断单链表是否带环

  1. 所以要判断一个单链表是否带环,其实最简单最暴力的方法就是把这个链表遍历一遍看程序有没有死循环,如果死循环了的话,那就是带环了。当然这种方法是不推荐的哦。
  2. 一般我们可以这样子来想,对于这个单链表的话,给他两个指针一个指针走得快(fast),一个指针走得慢(slow),我们让这两个指针都从头指针开始走动,fast指针,每次走两步,slow指针每次走一步,如果这个链表带环的话,那么这两个指针一定可以相遇在这个环中。
    所以我们只需要判断最后(fast==slow)成立与否的问题了。

代码如下:

//检查链表是否带环
pNode CheckCycle(pList pList)
{
    pNode fast = pList;
    pNode slow = pList;
    fast = fast->next->next;
    slow = slow->next;
    while (slow != fast && fast != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    //不带环,返回的是NULL
    if (fast == NULL)
    {
        return NULL;
    }
    //带环,返回的是快慢指针的相遇点
    return slow;
} 

求环的长度

这个问题更加的简单了,上面不是已经求出了快慢指针的相遇点,该点是环内的一个点,那木只需要从该点进行一番遍历就好了,就可以求出环的长度。
代码如下:

//求环的长度
//将相遇点给进来,进行遍历即可
 int GetCycleLength(pList meet)
{
    int len = 1;
    pNode cur = meet->next;
    while (cur != meet)
    {
        cur = cur->next;
        len++;
    }
    return len;
}

求环的入口点

求环的入口点

对于思路在上面讲解清楚,所以接下来就来将代码实现,只要理解来这个思路,其实代码特别好写,接下来看看代码该如何来写:
代码:

//求环的入口点
//只需要对于相遇点以及链表的起点进行遍历,当两个指针相等的话,就求得该带环单链表的环的入口点
pNode StartCycle(pList pList, pNode meet)
{
    while (pList != meet)
    {
        pList = pList->next;
        meet = meet->next;
    }
    return pList;
}

猜你喜欢

转载自blog.csdn.net/qq_40399012/article/details/81779291