什么是有效的算法来查找单链表是否是循环/循环的?
2022-09-01 04:06:41
如何查找单一链表是否为循环/循环?我试图搜索,但找不到令人满意的解决方案。如果可能的话,你能提供伪代码或Java实现吗?
例如:
→ → → → → → ,其中第二个实际上是列表的第三个元素。1
3
5
71
45
7
5
5
如何查找单一链表是否为循环/循环?我试图搜索,但找不到令人满意的解决方案。如果可能的话,你能提供伪代码或Java实现吗?
例如:
→ → → → → → ,其中第二个实际上是列表的第三个元素。1
3
5
71
45
7
5
5
标准答案是在开始时取两个迭代器,将第一个迭代器递增一次,将第二个迭代器递增两次。检查它们是否指向同一对象。然后重复,直到递增两倍的那个要么击中第一个,要么到达终点。
此算法在列表中查找任何循环链接,而不仅仅是它是一个完整的圆圈。
伪代码(不是Java,未经测试 - 在我的头顶上)
bool hasCircle(List l)
{
Iterator i = l.begin(), j = l.begin();
while (true) {
// increment the iterators, if either is at the end, you're done, no circle
if (i.hasNext()) i = i.next(); else return false;
// second iterator is travelling twice as fast as first
if (j.hasNext()) j = j.next(); else return false;
if (j.hasNext()) j = j.next(); else return false;
// this should be whatever test shows that the two
// iterators are pointing at the same place
if (i.getObject() == j.getObject()) {
return true;
}
}
}
一种称为弗洛伊德算法的简单算法是有两个指针,a和b,它们都从链表中的第一个元素开始。然后,在每个步骤中,您递增一次,b递增两次。重复此步骤,直到到达列表的末尾(无循环)或 a == b(链表包含循环)。
另一种算法是布伦特算法。