我是Java的初学者,目前正在尝试解决“树”一章中的练习。
一棵树由这些节点组成。
enter image description here。节点拥有一个对应于整数的值。
除了树根上的节点外,一个节点始终只有另一个引用它的节点。
如果节点的右侧或左侧没有子代,则相应的引用为null
。
左侧子树中任何子项所拥有的价值小于其父项的价值,右侧子树中任何子项所拥有的价值均大于其父项的价值。
树的高度在0到10万节之间。
我正在尝试实现一种find(int v)
方法,该方法返回持有值v
的节点,如果该节点不存在,那么find将必须返回null
。
这是我所做的,直到知道,但我有点迷茫:
class Node{
Node left, right;
int value;
public Node find (int v){
Node result = null;
if (this.left != null) result = find(v);
if (this.value == v) return this;
if (result == null && this.right != null)
result = find(v);
return result;
}
public static void main (String[] args){
Node n = smallNode.find(8);
System.out.println(n);
n = LargestNode.find(0);
System.out.println(n);
}
}
我在这一行得到StackoverOverflowError
:
if (this.left != null) result = find(v);
我在做什么错?我找不到为什么会引发这种异常。
答案 0 :(得分:2)
您应该首先检查该值,如果节点具有您要查找的值,则返回this
。如果未选中,则可以从当前节点继续并向右移动,一旦返回,请检查具有给定值的结果,如果正确,则返回该Node,否则返回左侧给出的值。它将是具有所需值的Node或为null。
public Node find (int v){
Node result = null;
//check for value first
if (this.value == v) return this;
//check if you can go any further from the current node
if(this.left == null && this.right == null) return null;
//now go right
result = this.right.find(v);
//check the node
if(result != null && result.value == v) return result;
//if not found return whatever is returned by searching left
return this.left.find(v);
}
答案 1 :(得分:1)
您的find
方法不断使用接收到的相同参数进行调用。因此,您实际上并没有遍历任何节点。相反,您会一次又一次地检查同一节点。
由于find
不断不断地自我调用,因此在某个时刻调用堆栈用完了。这就是为什么您得到StackOverflowError。
尝试使用调试器逐步完成find
,但这并没有达到您的预期。
答案 2 :(得分:1)
public class Node {
Node left,right;
int value;
// Solution 1
public Node find(int v){
if (v == this.value) return this;
if (v > this.value && this.right != null) return this.right.find(v);
if (v < this.value && this.left != null) return this.left.find(v);
return null;
}
// Solution 2
public Node find2(int v){
Node node = this;
while (node!=null){
if (v == node.value)
return node;
if (v > node.value)
node= node.right;
else
node= node.left;
}
return null;
}
}
答案 3 :(得分:0)
您的代码不完整(有错别字)。您没有显示如何声明LargestNode或smallNode。
但是,由于您引用的行将继续在同一节点上递归调用,因此发生了堆栈溢出。添加一些调试信息以证明这一点(查找的第一行,进行类似System.out.println("called by "+Integer.toString(this.hashCode());
的操作。例如,我怀疑这是另一种错字,可能是if(this.left!=null) result = this.left.find(v)
。