查找二进制树中是否包含值

时间:2019-03-11 12:18:50

标签: algorithm tree

我有一个TreeTree类,如下所示:

class TreeNode {
    int value;
    TreeNode left;
    TreeNode right;

public TreeNode(int x) {
    value = x;
}

我想编写一个递归方法 contains(int i),如果 i 是树中节点的值,该方法将返回true,否则返回false。 / p>

根据我的理解,不必对二叉树进行排序,因此我不应该将当前节点的值与我们正在搜索的值进行比较。因此,我编写了以下方法:

public boolean contains(int i) {
    if (value == x) {
        return true;
    } else {
        if (left != null) {
            return left.find(i);
        }
        if (right != null) {
            return right.find(i);
        }
    }
    return false;
}

我对此的想法是,它将检查当前节点的值是否等于我们要搜索的值,如果不等于,则应使用左节点和右节点递归调用该方法(如果它们不为null) ,否则该方法将返回false。

如果我们要搜索与树左侧节点相对应的值,则此方法最终将返回true,但是一旦我们搜索了一个超出该值(向右)的值,它将返回false。我已经花了好几个小时思考这个问题,我敢肯定有一个相对微不足道的解决方案,但我似乎无法解决。

6 个答案:

答案 0 :(得分:1)

类似这样的东西:

public boolean contains(int i) {
    return value == i ||
       left != null && left.contains(i) ||
       right != null && right.contains(i);
}

答案 1 :(得分:0)

返回递归调用的结果而不先检查是true还是false是不正确的。

如果左子树搜索返回false,则仍应搜索右子树。

public boolean contains(int i) {
    if (value == x) {
        return true;
    } else {
        boolean found = false;
        if (left != null) {
            found = left.find(i);
        }
        if (!found && right != null) {
            found right.find(i);
        }
        return found;
    }
}

答案 2 :(得分:0)

您的代码似乎不符合要求,因为TreeNode类没有find(int i)方法。

我认为contains()方法应该看起来像这样:

public boolean contains(TreeNode node, int i) {
  boolean result = node.value == i;
  if (left != null) result |= contains(node.left, i);
  if (right != null) result |= contains(node.right, i);
  return result;
}

当然,您可以在找到值后终止并跳过两个!= null检查,方法是在该方法的开头添加一个额外的递归底部:

public boolean contains(TreeNode node, int i) {
  if (node == null) return false;
  if (node.value == i) return true;
  return contains(node.left, i) || contains(node.right, i);
}

可以进一步简化为单线:

public boolean contains(TreeNode node, int i) {
  return node != null && 
        (node.value == i || contains(node.left, i) || contains(node.right, i));
}

答案 3 :(得分:0)

这似乎更正确:

public boolean contains(int i) {
    if (value == x) {
        return true;
    } else {
        if (left != null && left.find(i)) {
            return true;
        }
        if (right != null && right.find(i)) {
            return true;
        }
    }
    return false;
}

答案 4 :(得分:0)

    if (left != null) {
        return left.find(i);
    }

这是问题。如果同时存在一个左节点和一个右节点,则代码将仅返回是否在左侧找到了任何内容。

相反,您需要类似的东西:

    boolean found = false;
    if (left != null) {
        found = left.find(i);
    }
    if (!found && right != null) {
        found = right.find(i);
    }
    return found;

答案 5 :(得分:0)

您的实现更喜欢左子树;它不能在两个子树中正确搜索。此问题可以通过以下方式解决。

public boolean contains(int i) {
    boolean Result = value == x;
    if (left != null) {
        Result |= left.find(i);
    }
    if (right != null) {
        Result |= right.find(i);
    }
    return Result;
}

可以进一步优化此实现,以便尽早返回。

public boolean contains(int i) {
    boolean Result = value == x;
    if (!Result && left != null) {
        Result |= left.find(i);
    }
    if (!Result && right != null) {
        Result |= right.find(i);
    }
    return Result;
}