我想在下面的节点结构中列出列表中的循环或递归.我该如何识别?
public class EntityNode { private EntityNode nextNode; // Points to the next node }
例,
Node1 -> Node2 -> Node3 -> Node4 -> Node5 -> Node6 -> Node4
在这里,您可以看到Node6指向Node4,这里出现了循环或递归,我的代码将变为无限.那么如果我想找出具有最佳性能水平的这种情况呢?
解决方法
这实际上是我听过几次的面试问题.虽然我从未试图实现任何类型的循环检测,但大多数访问者似乎喜欢的答案是遍历列表并将访问过的节点存储在哈希表中.如果在存储到表中时发生冲突,则表示列表中有一个循环.
编辑:为了尝试为该示例提供一些代码,这是我可能会尝试做的(假设您有某种LinkedList< EntityNode>对象).我更新了这个以使用HashSet而不是HashMap,因此它更直接(正如PM 77-1所指出的).
public bool detectLoop(LinkedList<EntityNode> list) { Set<EntityNode> nodeSet = new HashSet<EntityNode>(); EntityNode curNode = list.getHead(); boolean loopDetected = false; if(curNode != null) { while(curNode.getNextNode() != null && !loopDetected) { cureNode = curNode.getNextNode(); loopDetected = !nodeSet.add(curNode); } } return loopDetected; }
我没有机会测试这个,但这应该有效.原因是如果此集合尚未包含指定元素,则HashSet的add()方法返回true.因此,如果集合中已存在EntityNode,则它将返回false,这意味着检测到了循环.
由于我的答案有所改变,我想说还有其他解决方案.在这个主题中已经指出的另一个是乌龟和野兔算法.您可以在this thread或this wiki page找到更多相关信息.