以下是我在链表中检测周期的代码:
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");
有没有办法摆脱循环中的代码重复?
我是否正确地假设在乌龟向前迈出一步之后我不需要检查?在我看来,乌龟在野兔之前永远不会到达清单的末尾(与寓言相反)。
还有其他简化/美化此代码的方法吗?
答案 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++)
循环。除此之外,我认为你已经拥有了最简单的代码。