Два указателя инициализируются в начале списка. Один указатель движется вперед один раз на каждом шаге, а другой - два раза вперед на каждом шаге. Если более быстрый указатель снова встречается с более медленным, в списке есть петля. В противном случае цикл не выполняется, если более быстрый достигает конца списка.
Пример кода ниже реализован в соответствии с этим решением. Более быстрый указатель - pFast, а медленный - pSlow.
bool HasLoop(ListNode* pHead)
{
if(pHead == NULL)
return false;
ListNode* pSlow = pHead->m_pNext;
if(pSlow == NULL)
return false;
ListNode* pFast = pSlow->m_pNext;
while(pFast != NULL && pSlow != NULL)
{
if(pFast == pSlow)
return true;
pSlow = pSlow->m_pNext;
pFast = pFast->m_pNext;
if(pFast != NULL)
pFast = pFast->m_pNext;
}
return false;
}
Это решение доступно на моем блоге . В блоге обсуждается еще одна проблема: что такое узел входа, когда в списке есть цикл / цикл?