我的乌龟与野兔种族能否得到改善?

时间:2011-03-17 15:56:49

标签: algorithm linked-list code-duplication control-flow

以下是我在链表中​​检测周期的代码:

do
{
    hare = hare.next();
    if (hare == back) return;

    hare = hare.next();
    if (hare == back) return;

    tortoise = tortoise.next();
}
while (tortoise != hare);
throw new AssertionError("cyclic linkage");
  1. 有没有办法摆脱循环中的代码重复?

  2. 我是否正确地假设在乌龟向前迈出一步之后我不需要检查?在我看来,乌龟在野兔之前永远不会到达清单的末尾(与寓言相反)。

  3. 还有其他简化/美化此代码的方法吗?

4 个答案:

答案 0 :(得分:2)

  

有没有办法摆脱代码   循环中的重复?

怎么样:

for(int i = 0; i < 2; i++)
{
    hare = hare.next();
    if (hare == back) return;
}

 tortoise = tortoise.next();

无论如何,这不是一次巨大的进步。

  

我认为在乌龟向前迈出一步之后我不需要检查是对的吗?

是的,正如你正确推理的那样,乌龟总是落后于野兔之前移动;所以乌龟总是覆盖以前所覆盖的地面。

如果数据结构在比赛中因任何原因发生变异,那么这当然不再适用(但如果是这样,你会遇到更大的问题)。

  

任何其他简化/美化的方法   这段代码?

不是我能想到的。

答案 1 :(得分:1)

这是我改进的代码,基于Steve的评论(将后哨节点链接到自身):

while (hare != back)
{
    tortoise = tortoise.next();
    hare = hare.next().next();
    if (hare == tortoise) throw new AssertionError("cyclic linkage");
}

我没有看到任何会破坏客户端代码的地方,我的单元测试证实了这一点。太棒了:))

答案 2 :(得分:1)

您可以使用单个if语句并使用||是短路运算符的事实。这有点简洁,但可能更难理解,仍然存在代码重复。

    do
    {
        if ((hare = hare.next()) == back || 
            (hare = hare.next()) == back) 
                return;            
        tortoise = tortoise.next();
    }
    while (tortoise != hare);

答案 3 :(得分:0)

为避免重复,您可以使用for (int i = 0; i < 2; i++)循环。除此之外,我认为你已经拥有了最简单的代码。