一、判断该链表是否有环
使用双指针,前指针走得快,后指针走得慢,如果有环,前指针能够在后面追上慢指针
#include<iostream>
struct listNode
{
int m_nValue;
listNode* m_Next;
listNode(int _value) :m_nValue(_value){}
};
listNode* MeetingNode(listNode* pHead)
{
if (pHead == nullptr)return nullptr;
listNode* pSlow = pHead->m_Next;
if (pSlow == nullptr)return nullptr;
listNode* pFirst = pSlow->m_Next;
while (pFirst && pSlow)
{
if (pSlow == pFirst)
return pFirst;
pSlow = pSlow->m_Next;
pFirst = pFirst->m_Next;
if (pFirst != nullptr)
pFirst = pFirst->m_Next;
}
return nullptr;
}
二、找到环的入口
计算得到环的节点数
将指针1前进环的节点数
将指针2从头节点开始,与指针1同步移动,相遇点即入环口
listNode* EntryNodeOfLoop(listNode* pHead)
{
if (pHead == nullptr)return nullptr;
listNode* meetingNode = MeetingNode(pHead);//找到相遇点
int loopCount = 1;
listNode* pNode1 = meetingNode;
while (pNode1 != meetingNode)//计算环节点数
{
pNode1 = pNode1->m_Next;
++loopCount;
}
pNode1 = pHead;
for (int i = 0;i < loopCount;++i)//将指针1从头节点向后移动环中节点数
{
pNode1 = pNode1->m_Next;
}
listNode* pNode2 = pHead;
while (pNode1 != pNode2)//指针2与指针1同步移动,相遇点即入环口
{
pNode1 = pNode1->m_Next;
pNode2 = pNode2->m_Next;
}
return nullptr;
}