Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,求出该环的起点与长度的算法

判环

我们定义两个指针,一快一慢,慢指针每次走一步,快指针每次走两步;当两个指针从链表的同一节点开始移动时,若链表中无环,则快指针一直在慢指针前;否则,快指针会先于慢指针入环,且会在慢指针跑满环中一圈之前,追上快指针!。

  1. slow=head,fast=head;
  2. while(fast!=nullptr){
  3. if(fast->next==nullptr)
  4. return false;
  5. fast=fast->next->next;
  6. slow=slow->next;
  7. if(fast==slow)
  8. return true;
  9. }
  10. return false;

求环的起点与长度

Floyd判圈算法 - 图1
基于Floyd判圈算法, 设置快慢指针fast和slow,假设fast和slow在P点相遇,且fast已跑n圈,可得出如下结论

Floyd判圈算法 - 图2
联立后,可得出Floyd判圈算法 - 图3
即环外距离等于【相遇点与环起点距离c】和【多圈环长度】之和
故当快慢指针相遇时,设置新ptr指针指向头结点。并令ptr和slow指针同步运动,直到两指针相遇时,便为环的起点。

  1. {
  2. auto slow=head,fast=head;
  3. while(fast!=nullptr){
  4. if(fast->next==nullptr)
  5. return nullptr;
  6. fast=fast->next->next;
  7. slow=slow->next;
  8. if(fast==slow){
  9. auto ptr=head;
  10. while(ptr!=slow){
  11. slow=slow->next;
  12. ptr=ptr->next;
  13. }
  14. return ptr;
  15. }
  16. }
  17. return nullptr;
  18. }