Java 为什么在给定目标值的BST中查找最接近的值时,我得到了错误的答案?

Java 为什么在给定目标值的BST中查找最接近的值时,我得到了错误的答案?,java,recursion,tree,binary-search-tree,Java,Recursion,Tree,Binary Search Tree,正确答案和我的答案之间只有一个区别,那就是,我遍历整个树,而不是将目标值与节点值进行比较,并在每次递归中删除树的一半。请帮我解释一下。谢谢 我的代码: import java.util.*; class Program { public static int findClosestValueInBst(BST tree, int target) { //int closest = Integer.MAX_VALUE; // int val = 0;

正确答案和我的答案之间只有一个区别,那就是,我遍历整个树,而不是将目标值与节点值进行比较,并在每次递归中删除树的一半。请帮我解释一下。谢谢

我的代码:

import java.util.*;

class Program {
     public static int findClosestValueInBst(BST tree, int target) {
         //int closest = Integer.MAX_VALUE;
        // int val = 0;
         int vl = findClosestValueInBst1(tree, target, tree.value);
         return vl;
     }

  public static int findClosestValueInBst1(BST tree, int target, int val) {
    //  System.out.println((closest + "   " + Math.abs(tree.value - target)));
        //c = closest;
        if(( Math.abs(target - tree.value)) < ( Math.abs(target - val))){
            System.out.println(val);
            val = tree.value;
            
        }
    if(tree.left != null){
        return findClosestValueInBst1(tree.left, target, val);
    }
    if(tree.right != null){
        return findClosestValueInBst1(tree.right, target, val);
    }
    return val;
  }

  static class BST {
    public int value;
    public BST left;
    public BST right;

    public BST(int value) {
      this.value = value;
    }
  }
}
import java.util.*;
班级计划{
公共静态int findClosestValueInBst(BST树,int目标){
//int最近值=整数最大值;
//int-val=0;
int vl=findClosestValueInBst1(树,目标,树.value);
返回vl;
}
公共静态int-findClosestValueInBst1(BST树,int-target,int-val){
//System.out.println((最近的+“”+Math.abs(tree.value-target));
//c=最近的;
if((Math.abs(target-tree.value))<(Math.abs(target-val))){
系统输出打印项次(val);
val=tree.value;
}
if(tree.left!=null){
返回findClosestValueInBst1(tree.left,target,val);
}
if(tree.right!=null){
返回findClosestValueInBst1(tree.right,target,val);
}
返回val;
}
静态类BST{
公共价值观;
公共BST左;
公共BST权利;
公共BST(整型值){
这个值=值;
}
}
}
问题树-根=10, 节点->[10,15,22,13,14,5,5,2,1], 目标:12, 我的产出:10, 正确答案:13,

import java.util.*;

class Program {
     public static int findClosestValueInBst(BST tree, int target) {
         //int closest = Integer.MAX_VALUE;
        // int val = 0;
         int vl = findClosestValueInBst1(tree, target, tree.value);
         return vl;
     }

  public static int findClosestValueInBst1(BST tree, int target, int val) {
    //  System.out.println((closest + "   " + Math.abs(tree.value - target)));
        //c = closest;
        if(( Math.abs(target - tree.value)) < ( Math.abs(target - val))){
            System.out.println(val);
            val = tree.value;
            
        }
    if( target < tree.value && tree.left != null){
        return findClosestValueInBst1(tree.left, target, val);
    } else
            if(target > tree.value && tree.right != null){
        return findClosestValueInBst1(tree.right, target, val);
    } else
    return val;
  }

  static class BST {
    public int value;
    public BST left;
    public BST right;

    public BST(int value) {
      this.value = value;
    }
  }
}

import java.util.*;
班级计划{
公共静态int findClosestValueInBst(BST树,int目标){
//int最近值=整数最大值;
//int-val=0;
int vl=findClosestValueInBst1(树,目标,树.value);
返回vl;
}
公共静态int-findClosestValueInBst1(BST树,int-target,int-val){
//System.out.println((最近的+“”+Math.abs(tree.value-target));
//c=最近的;
if((Math.abs(target-tree.value))<(Math.abs(target-val))){
系统输出打印项次(val);
val=tree.value;
}
if(targettree.value&&tree.right!=null){
返回findClosestValueInBst1(tree.right,target,val);
}否则
返回val;
}
静态类BST{
公共价值观;
公共BST左;
公共BST权利;
公共BST(整型值){
这个值=值;
}
}
}

该树如下所示:

     10
     /\
    5  15
   /   /\
  2   13 22
 /     \
1      14
您的代码实际上并没有遍历整个树。此代码:

if(tree.left != null){
    return findClosestValueInBst1(tree.left, target, val);
}
if(tree.right != null){
    return findClosestValueInBst1(tree.right, target, val);
}
return val;
检查左子树是否存在(并忽略右子树)。否则,请检查右子树是否存在。否则停止递归。这是因为一旦到达
return
语句,整个方法就停止在那里,之后的行就不会执行

因此,您的代码总是首选左子树,而不考虑节点实际存储的数字。所以一开始,你就走错了方向-你在寻找13,而当前节点是10,一个更接近的值必须大于10,即在正确的子树中

实际遍历整个树的实现类似于:

public static int findClosestValueInBst(BST tree, int target) { // no need for the val argument!
    int leftClosest = tree.value;
    int rightClosest = tree.value;
    if(tree.left != null){
        leftClosest = findClosestValueInBst1(tree.left, target);
    }
    if(tree.right != null){
        rightClosest = findClosestValueInBst1(tree.right, target);
    }
    if (target - leftClosest < rightClosest - target) {
        return leftClosest;
    } else {
        return rightClosest;
    }
}
public static int findClosestValueInBst(BST树,int目标){//不需要val参数!
int leftClosest=tree.value;
int rightmestest=tree.value;
if(tree.left!=null){
leftClosest=findClosestValueInBst1(tree.left,target);
}
if(tree.right!=null){
rightClosest=findClosestValueInBst1(tree.right,target);
}
if(目标-左最近<右最近-目标){
返回最左;
}否则{
返回最右;
}
}

但既然你能更快地完成,为什么还要费事呢

谢谢@Sweeper。我还尝试删除“return”关键字。这一次,我可以在我的输出中看到,整个树都被遍历了,但仍然得到了不正确的输出。@user08删除
返回值
对您没有帮助。这只是忽略了递归调用的结果,这是不应该做的。有关“遍历整个树”的可能实现,请参见我的编辑。非常感谢您的帮助!!!:D