我正在尝试查看二进制搜索树中是否包含值,并且我使用递归遍历树。问题是函数返回false作为调用堆栈上的最后一个值而不是true。
这是伪代码:
public boolean containsValue(Node node, Value v) {
if (node.value.equals(v)) {
return true;
}
containsValue(node.left, v); // <- search left tree
containsValue(node.right, v); // <- search right tree
return false;
}
这总是返回false。
但是我不能这样做,因为第二个return语句是死代码:
return containsValue(node.left, v);
return containsValue(node.left, v);
那我该如何解决这个问题?
答案 0 :(得分:7)
这解决了当前的问题,但这不是搜索二叉树的正确或有效方法,因为它没有做出左右看的决定,它只是笨拙地向左看,然后向右看。正确答案是here。
如果左侧节点包含它,或者(||
)右侧节点包含它,则返回true。
return containsValue(node.left, v) || containsValue(node.right, v);
请注意,如果左边包含它,它会短路并且不会向右看。
你甚至可以完成整个事情:
return node.value.equals(v) ||
containsValue(node.left, v) ||
containsValue(node.right, v);
答案 1 :(得分:3)
你去了
public boolean containsValue(Node node, Value value){
int result = node.value.compareTo(value);
if(result == 0){
return true;
}else if(result < 0){
if(node.left != null){
return containsValue(node.left, v);
}
return false;
}else{
if(node.right != null){
return containsValue(node.right, v);
}
return false;
}
}
这将检查当前节点的值与参数值的比较方式。如果参数值较小,则返回左子(<0)
的结果,如果它们相同则返回true (==0)
,如果pass by value较大则返回右子(>0)
的结果{ {1}}。这将持续到找到值或需要搜索的子项为空。
此方法完全使用二叉搜索树,因为它不检查所有变量,并且具有平均效率O(log(n))而只是查找通过所有节点的平均效率为O(n),这是最差的。
旁注:
获取具有该值的节点的方法基本相同,您只需将true
替换为node
,将false
替换为null
,将boolean
替换为Node
}
示例:
public Node getNode(Node node, Value value){
int result = node.value.compareTo(value);
if(result == 0){
return node;
}else if(result < 0){
if(node.left != null){
return containsValue(node.left, v);
}
return null;
}else{
if(node.right != null){
return containsValue(node.right, v);
}
return null;
}
}
答案 2 :(得分:1)
您可以检查任一分支是否返回true,并在尝试返回false之前传递该分支。
public boolean containsValue(Node node, Value v) {
if (node.value.equals(v)) {
return true;
} else if (containsValue(node.left, v)) {
return true;
} else if (containsValue(node.right, v)) {
return true;
}
return false;
}
答案 3 :(得分:0)
有些人喜欢单行:
public boolean containsValue(Node node, Value v) {
return node.value.equals(v) || containsValue(node.left, v) || containsValue(node.right, v);
}
答案 4 :(得分:0)
public boolean containsValue(Node node, Value v) {
if (node.value.equals(v)) {
return true;
}
else if(containsValue(node.left, v))
return true; // <- search left tree
else if(containsValue(node.right, v)) // <- search right tree
return true;
return false;
}
目前,您的函数也返回true,但仅适用于与搜索值匹配的节点,对于所有其他节点,它将返回false。因此,当在调用堆栈中向后/向上重复时,它最终会返回false作为最终答案。仅在树中的一个节点的情况下它才是正确的,并且它与搜索值匹配。
答案 5 :(得分:0)
由于其递归性质,该方法返回 false。在找到值后的递归函数中,它将将该值返回到方法的父副本,并根据代码返回到其父副本。我们需要以某种方式存储结果以将其用于递归方法的第一次调用。
简单来说,我们需要将结果存储在一个变量中,并将该变量作为递归函数的最终值返回。
对于程序员来说,我正在分享一个代码,以从中获得帮助并深入理解它。
public boolean contains (int i){
boolean result= false;
boolean flag = recursiveContains(root, i, result);
System.out.println(flag);
return flag;
}
public boolean recursiveContains(Node root, int i, boolean result)
{
// if root not null
if (root != null){
// if i value found in RandomBST
if (root.value == i) {
result = true; // result is used for understanding
return result;
}
else if (i < root.value) {
//if i smaller then root.value search i in leftchild
result = recursiveContains(root.left, i, result);
} else {
//if i>root.value search for i in rightchild
result = recursiveContains(root.right, i, result);
}
}
return result;
}
此外,我正在添加代码的图片说明。但这需要专注。我已经为 i=9 调用了上述函数。并展示了它是如何返回 true 的。它总共创建了 3 次 contains 方法调用。