检测链表中的多个循环

时间:2012-08-09 01:46:32

标签: c algorithm pointers data-structures linked-list

我想在以下情况下检测循环

1-2-3-4-5
|----------| ===> case 1

1-2-3-4-5
|-------|    ===> case 2

如果1个循环检测算法正常工作,但不适用于情况2。 我为案例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,然后查看是否有重复元素。

(实际上你可以将每个第十个节点添加到哈希表中,但是针对哈希表检查每个访问节点是否有重复项。)

如果您提前知道链表中有多少元素(并且未被修改),可以多次简单地遍历并查看下一个节点是否为空。