我想在以下情况下检测循环
1-2-3-4-5
|----------| ===> case 1
1-2-3-4-5
|-------| ===> case 2
如果1个循环检测算法正常工作,但不适用于情况2。 我为案例2做了干运行,我发现野兔指针正常结束。 另外我认为情况2是无效的单链表,因为它包含2个下一个指针。 案例2的假设是否正确? 整个场景是单链表吗?
答案 0 :(得分:2)
这是一个不涉及分配堆内存的循环检测解决方案:
struct Node {
int val;
struct node * next;
};
bool containsCycle(Node * head)
{
Node * walker = head;
NOde * fastWalker = head;
while(walker && fastWalker)
{
fastWalker = fastWalker->next;
if(walker == fastWalker)
return true;
if(fastWalker)
fastWalker = fastWalker->next;
if(walker == fastWalker)
return true;
walker = walker->next;
}
// Fell out of the loop, no cycle
return false;
}
此算法使用两个以不同速度前进的指针。如果列表中有一个循环,则两个指针在某一点上将彼此相等。
答案 1 :(得分:1)
我会根据你所问的一系列假设给出答案。
我猜你的格式搞砸了,你正在使用一个由一个节点结构构建的单链表,它有一个叫做“next”的指针。
我还假设您有一个指向列表第一个元素的指针,称为Root。
接下来,我假设您的算法包括存储root副本,然后遍历列表以查看是否返回root。
这适用于以下情况:
A -> B -> C -> D -> E //and E -> A.
但是如果
那就行不通A -> B -> C -> D -> E //and E -> B.
一种方法是在您走过时标记每个访问过的节点,方法是在结构中添加一个新字段,或者保留一个hashTable,然后查看是否有重复元素。
(实际上你可以将每个第十个节点添加到哈希表中,但是针对哈希表检查每个访问节点是否有重复项。)
如果您提前知道链表中有多少元素(并且未被修改),可以多次简单地遍历并查看下一个节点是否为空。