Похоже, вы проверяете только немедленные циклы в своей первой итеративной версии.(Вы не проверяете, есть ли у вас петля большего размера A -> B -> C -> A. Вы проверяете только петли типа A -> B -> A).Я предполагаю, что то, что вы представили, правильно и что вы хотите, хотя и странно.(Если у вас большой цикл, он будет продолжаться бесконечно).
Правильный и простой способ сделать то, что вы представили рекурсивно:
public boolean hasImmediateCycle(Node node) {
if (node == null || node.getNext() == null) {
return false;
} else if (node == node.getNext().getNext()) {
return true;
} else {
return hasImmediateCycle(node.getNext());
}
}
Если вы хотите, чтобы он проверялвсе возможные циклы, которые вам понадобятся, чтобы сделать это немного по-другому:
private boolean hasCycle(Node node, Set<Node> seen) {
if (node == null) {
return false;
} else if (seen.contains(node)) {
return true;
} else {
seen.add(node);
return hasCycle(node.getNext(), seen);
}
}
public boolean hasCycle(Node node) {
return hasCycle(node, new HashSet<Node>());
}
Это проверит все узлы seen
, если они снова появятся в ссылке next
.Это на самом деле использует .equals()
и .hashCode()
вашего Node
, поэтому важно, чтобы они реализовывались согласованно друг с другом.