快慢指针法检测环
环形的数据结构是一种常见的数据结构组织形式。它的一个好处是首尾相连,知道尾元素就能知道首元素,通常也只需保留一个跟踪节点或者迭代器。有时我们需要判断一个数据结构是否形成环,一个简单的方法是准备一个容器,将该数据结构的所有迭代器保存,然后遍历数据结构,每次读取一个元素时判断该元素是否已经在准备的容器中,时间复杂度\(O(N)\),空间复杂度\(O(N)\);另一个方法是使用快慢指针法,又叫做Floyd 判圈算法,过程是准备两个指针或者两个迭代器,其中一个步长是一个单位,另一个步长是两个单位,根据它们的相对速度,如果是在环中,它们最终会相遇。模型图如下:
在模型图中假设快指针与满指针在同一个位置,事实上,按照快慢指针法的方法,快指针与慢指针可以不在同一个位置。时间复杂度\(O(N)\),空间复杂度\(O(1)\)。
代码如下:
listCircular<int>::iterator fast_ = test.begin( );
listCircular<int>::iterator slow_ = test.begin( );
do {fast_ = fast_ + 2;++slow_;
} while( fast_ != slow_ );
if( fast_ == slow_ )// 标记为环
代码比较简洁,可以根据需要做一些改变,比如一些安全检查等。