我们可以设置两个指针,pFast和pSlow开始时都指向头结点,然后pFast一次向后移动两个节点,pSlow一次向后移动一个节点直到他们相遇
这样我们就得到了一个相遇点,如上图所示:
我们可以得到这样一个结论:
2(L+x) = L + nR + x
L + x = nR
取极值n=1可得: L = R - x;
也就是说从相遇点到交点的距离和头结点到交点的距离相等
然后把pSlow在指向头结点,pFast不变,两个指针每次向后移动一个结点直到他们相遇,则那个结点就是入口点
//判断链表是否带环,求入口点
PNode IsCircleList(PNode *pHead)
{
if (NULL == *pHead || NULL == pHead)
{
return NULL;
}
PNode pFast = (*pHead)->next->next;
PNode pSlow = (*pHead)->next;
while (pFast != pSlow && NULL != pFast && NULL != pFast->next)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
}
//说明这个链表不是带环链表
if (NULL == pFast || NULL == pFast->next)
{
return NULL;
}
pSlow = *pHead;
while (pSlow != pFast)
{
pSlow = pSlow->next;
pFast = pFast->next;
}
return pSlow;
}

本文介绍了一种利用快慢指针检测链表中是否存在环并找到环的入口点的方法。通过设置两个指针,一个快指针每次移动两个节点,一个慢指针每次移动一个节点,当两指针相遇时,重新设置一个指针到链表头,同时移动两指针直至再次相遇即为入口点。
805

被折叠的 条评论
为什么被折叠?



