1,实现思路
如何判断一个单链表是否有环?
我们可以定义两个指针,第一个指针一次遍历一步,第二个指针一次遍历两步,如果第二个指针指向NULL,则单链表无环,如果第二个指针与第一个指针相遇,则说明有环。
2,代码实现
LNode* HasCircle(LNode *phead)
{
if(phead == NULL) return NULL;
LNode *pFast = phead;
LNode *pSlow = phead;
while(pFast != NULL && pFast->next != NULL)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
if(pFast == pSlow)
return pFast;
}
return NULL;
}
如果有环,返回环的入口地址。
3,实现思想
如果有环,通过返回相遇的节点,我们可以求出环的长度,然后我们定义两个指针,第一个指向头结点,并且向后遍历环的长度,第二个指针指向头结点,然后两个指针开始同时向后遍历,当两个指针相等的时候,此时的地址就是环的入口地址。
4,代码实现
LNode *searchEntranceNode(LNode *phead)
{
LNode *MeetNode = HasCircle(phead);
if(MeetNode == NULL) return NULL;
LNode *pNode1 = MeetNode->next;
int length = 1; //环的长度
while(pNode1 != MeetNode)
{
pNode1 = pNode1->next;
++length;
}
pNode1 = phead;
while(length--)
{
pNode1 = pNode1->next;
}
LNode *pNode2 = phead;
while(pNode1 != pNode2)
{
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pNode1;
}
5,总结单链表
链表的操作在很多方面都会用到指针,如果一个指针不够用,可以用两个指针来实现,比如找单链表的第K个节点,找单链表的中间节点,找两个单链表的相交节点(下一篇博客实现)等等都会用到快慢指针,所以掌握快慢指针的用法,真的很重要!!!