判断单链表是否带环?若带环求出环的长度?求出环的入口点?

如何判断单链表是否带环?
单链表带环:
这里写图片描述
  以上这几种情况为链表里面带有环。
  那么如何判段链表里面是否有环呢?
  我们设置两个指针fast,slow,两个指针均从头结点开始移动,快指针每次走两步,慢指针每次走一步,如果链表带环,在环中两个指针会相遇,则证明该单链表带环。
这里写图片描述
  快慢指针在结点4处相遇,则证明该单链表有环,结点4是相遇点。
  那么是否可以让快指针一次走2,3,4或者更多步,慢指针一次走一步???
  不可以!!!
  如果让快指针一次走n步,慢指针一次走一步,而环的长度为n-1则两个指针永远不会相遇。。

#define DataType int
typedef struct Node{
    DataType data;
   struct Node* next;
}linklist;
linklist*  CircleLinkList(linklist *head)
{
    linklist *fast = NULL;
    linklist *slow = NULL;
    if (head == NULL)
        return 0;
    fast = head;
    slow = head;
    while (fast != NULL&&fast->next!=NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
        if (fast == slow)
        {
            return fast;
        }
    }
    return NULL;
}

如何求出带环单链表环的长度?
  设置两个指针pre,cur,均指向相遇点,指针cur不动,指针pre每次移动一步,判断pre->next是否等于cur,若不等于计数器++,直到两个指针相等,返回计数器的大小。
这里写图片描述

int GetCircleLength(linklist *head)
{
    linklist *cur = CircleLinkList(head); 
    //该函数返回的是函数的相遇点
    linklist *pre = cur;  
    int count = 1;
    while (pre->next!=cur)
    {
        count++;
        pre = pre->next;
    }
    return count;
}

如何求出带环单链表环的入口点?
  设置两个指针pre,ret,pre从头指针处开始移动,cur从相遇点开始移动,两者相遇的点即入口点。
这里写图片描述

#define DataType int
typedef struct Node{
    DataType data;
   struct Node* next;
}linklist;
linklist * GetCircleEnter(linklist *head, linklist * meet)
{
    linklist *pre = NULL;
    linklist *ret = NULL;

    if (head == NULL)
        return NULL;
    pre = head;
    ret = meet;
    while (pre != ret)//meet为相遇点
    {
        pre = pre->next;
        ret = ret->next;
    }
    return ret;
}

猜你喜欢

转载自blog.csdn.net/zhao_miao/article/details/81239232