在 Java 中遍历二叉搜索树时出现 StackOverflowError
StackOverflowError while traversing a binary search tree in Java
我有一个方法 returns BST 中最深的节点。我有这个引发 Whosebug 错误的代码:
public int getDeepestNode(AvlNode head) {
if (head == null) {
return 0;
} else {
return (Math.max(getDeepestNode(head.getLeftNode()), getDeepestNode(head.getRightNode())) + 1);
}
}
对我来说看起来不错,为什么会引发错误?
getDeepestNode 必须在堆栈上重复出现。
您很可能在 AVL 树中有一个循环。命名 head
可能已经表明了不洁的思想。调试有帮助。
或者,您可以将代码强化为:
public int getDeepestNode(AvlNode head) {
return getDeepestNodeSafe(head, new ArrayList<AvlNode>());
}
public int getDeepestNodeSafe(AvlNode head, List<AvlNode> pathFromRoot) {
if (head == null) {
return 0;
} else {
if (pathFromRoot.contains(head)) {
StringBuilder sb = new StringBuilder("Cycle: ");
for (AvlNode node : pathFromRoot) {
if (node == head) {
sb.append("***");
}
sb.append(node).append("; ");
}
Logger.getLogger(getClass().getName()).log(Level.WARN, sb.toString());
return 0;
}
pathFromRoot.add(head);
int depth = Math.max(getDeepestNodeSafe(head.left, pathFromRoot),
getDeepestNodeSafe(head.right), pathFromRoot) + 1;
pathFromRoot.remove(pathFromRoot.size() - 1); // Undo
return depth;
}
}
抛出 IllegalStateException 肯定会更好,但使用此代码您可能会更快(或更快)发现错误。
我有一个方法 returns BST 中最深的节点。我有这个引发 Whosebug 错误的代码:
public int getDeepestNode(AvlNode head) {
if (head == null) {
return 0;
} else {
return (Math.max(getDeepestNode(head.getLeftNode()), getDeepestNode(head.getRightNode())) + 1);
}
}
对我来说看起来不错,为什么会引发错误?
getDeepestNode 必须在堆栈上重复出现。
您很可能在 AVL 树中有一个循环。命名 head
可能已经表明了不洁的思想。调试有帮助。
或者,您可以将代码强化为:
public int getDeepestNode(AvlNode head) {
return getDeepestNodeSafe(head, new ArrayList<AvlNode>());
}
public int getDeepestNodeSafe(AvlNode head, List<AvlNode> pathFromRoot) {
if (head == null) {
return 0;
} else {
if (pathFromRoot.contains(head)) {
StringBuilder sb = new StringBuilder("Cycle: ");
for (AvlNode node : pathFromRoot) {
if (node == head) {
sb.append("***");
}
sb.append(node).append("; ");
}
Logger.getLogger(getClass().getName()).log(Level.WARN, sb.toString());
return 0;
}
pathFromRoot.add(head);
int depth = Math.max(getDeepestNodeSafe(head.left, pathFromRoot),
getDeepestNodeSafe(head.right), pathFromRoot) + 1;
pathFromRoot.remove(pathFromRoot.size() - 1); // Undo
return depth;
}
}
抛出 IllegalStateException 肯定会更好,但使用此代码您可能会更快(或更快)发现错误。