【问题标题】:contains-method in binary tree always return false java二叉树中的包含方法总是返回 false java
【发布时间】:2014-06-30 19:42:14
【问题描述】:

有人能解释一下为什么这个方法总是返回 false 吗?即使语句if(value == node.getValue()) 为真,该方法也返回假。与递归有关吗?我通过使用布尔变量来解决它,但我仍然很好奇为什么这不起作用。谢谢。

public boolean contains(Node node, Integer value) {

    if(node != null && node.hasValue()) 
        if(value == node.getValue()) 
            return true;

    if(node.hasLeft())
        contains(node.getLeft(), value);
    if(node.hasRight())
        contains(node.getRight(), value);

    return false;
}

我的解决方案(bool 是一个实例变量):

public boolean contains2(Node node, Integer value) {

    if(node != null && node.hasValue()) 
        if(value == node.getValue()) 
            bool = true;

    if(node.hasLeft())
        contains2(node.getLeft(), value);
    if(node.hasRight())
        contains2(node.getRight(), value);

    return bool;
}

【问题讨论】:

  • 您通过“使用布尔变量”解决了这个问题?你能发布同样有效的代码吗?
  • @PM 77-1 否。它通过了if(value == node.getValue()),但仍然返回 false。
  • 啊,是的。您正在解决一个事实,即您没有返回递归调用的结果。请参阅我的(以及其他几个类似的)答案。

标签: java binary-tree


【解决方案1】:

你的递归调用

contains(node.getLeft(), value);

正在将值返回给您,但您从未对该值执行任何操作。相反,您忽略它,并且在遍历所有节点之后,无论如何您都返回 false。您需要返回递归调用的值,这是您如何使用代码完成此操作的方法:

private boolean contains(Node node, Integer value) {
    if (node.getValue() == value) {
        return true;
    }

    boolean contains = false;
    if (node.hasLeft()) {
        contains = contains(node.getLeft(), value);
    }
    if (!contains && node.hasRight()) {
        contains = contains(node.getRight(), value);
    }

    return contains;
}

为了测试我使用了:

public static void main(String[] args) throws Exception {

    Node top = new Node(5);
    top.setLeft(new Node(3));
    top.setRight(new Node(7));
    top.getLeft().setLeft(new Node(1));
    System.out.println("Contains 5? " + contains(top, 5));
    System.out.println("Contains 3? " + contains(top, 3));
    System.out.println("Contains 7? " + contains(top, 7));
    System.out.println("Contains 9? " + contains(top, 9));

}

这给了我输出:

Contains 5? true
Contains 3? true
Contains 7? true
Contains 9? false

【讨论】:

  • 谢谢。但我还是不明白它怎么能通过if(value == node.getValue())-test 而不返回true?
  • @TheEagle 你了解递归的工作原理,或多或少?您从某个地方(主要或其他)调用了contains,然后contains 调用了自己,然后contains 调用了自己,直到其中一个找到了值。 main->contains->contains->contains。最终的contains 返回true,但它不直接返回main,而是从调用它的那一点返回到调用它的contains。然后从那一点继续执行。下一个被执行的returnreturn false
  • 博客对我的反应击败了我。我已经更新了我的答案,它显示了如何在没有实例变量的情况下访问返回调用并返回值。你不应该在这个问题中使用实例变量。我没有节点类来测试它,但这应该可以。
  • 刚刚写了一个快速的 Node 类来测试它。我发布的代码解决方案可以验证是否按预期工作。
  • 250代替7测试你的课程。
【解决方案2】:

除了前面提到的返回值问题...

就目前而言,您的逻辑看起来只有在您为搜索中的参数“值”传递完全相同的整数对象(引用)时才有效,该参数在填充树时使用。如果您要传入另一个 Integer 对象,即使其中具有相同的 int 值,您的 == 测试也会失败。要解决此问题,请改用 .equals 方法。当然,除非那是你的意图。

【讨论】:

  • 这很有帮助。谢谢。
  • 这其实是一个有趣的情况,因为integer cache的存在。例如,请参阅When comparing two Integers in Java does auto-unboxing occur?。所以结果会根据整数值是否低于 128 而有所不同。
  • 这是一个有趣的链接。听起来从编译器的角度来看,通过自动装箱(例如 Integer x = 10;)和显式构造(例如 Integer x = new Integer(10); 等)初始化 Integer 之间存在差异 - 没想到会这样.谢谢。
【解决方案3】:

如果你什么都不做,递归调用的返回值会丢失。试试看:

public boolean contains(Node node, Integer value) {

    if(node != null && node.hasValue()) 
        if(value == node.getValue()) 
            return true;
    boolean found = false 
    if(node.hasLeft())
        found = contains(node.getLeft(), value);
    if(!found && node.hasRight())
        found = contains(node.getRight(), value);

    return found;
}

【讨论】:

  • 您可以在第一个 if 语句中返回值。想象一下它是一棵二叉树的情况,它是通过添加 5、3、7 创建的。如果您使用您的方法并调用 .contains(root,7),它将返回 false,因为 7 不在左侧,它位于右侧。但是您只返回从左侧获得的任何结果。
  • @MikeElofson 我注意到了这个错误。您使用局部变量的解决方案有效。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2021-09-23
  • 2011-06-09
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
相关资源
最近更新 更多