计算O(LogN)中二进制搜索树内范围内的节点数

时间:2016-05-03 16:56:40

标签: algorithm data-structures binary-tree

给定BST和两个整数'a'和'b'(a< b),我们如何找到节点的数量,使得a<节点值< b,在O(log n)?

我知道可以在LogN时间内轻松找到a和b的位置,但如何在不进行遍历的情况下计算其间的节点,即O(n)?

4 个答案:

答案 0 :(得分:6)

在二进制搜索树的每个节点中,还要保留树中值小于其值的值的数量(或者,对于下面脚注中提到的不同树设计,其左子树中的节点)

现在,首先找到包含值a的节点。获取小于a的值的计数,该值已存储在此节点中。这一步是Log(n)。

现在找到包含值b的节点。获取存储在此节点中的值小于b的值。这一步也是Log(n)。

减去这两个计数,你有ab之间的节点数。此搜索的总复杂度为2 * Log(n)= O(Log(n))。

请参阅this video。教授通过使用Splay Trees解释了你的问题。

答案 1 :(得分:0)

将BST的inorder遍历存储在数组中(它将被排序)。搜索' a'和' b'将记录log(n)时间并得到他们的索引并采取差异。这将给出范围内的节点数量' a'到' b'。

空间复杂度O(n)

答案 2 :(得分:0)

简单的解决方案:

  • 从根节点开始检查
  • 如果Node处于范围内,则将其增加1并递归检查左子对象和右子对象
  • 如果Node不在范围内,则检查范围内的值。如果范围值小于根,则绝对可能的方案为左子树。否则检查右子树

    这是示例代码。希望能清除。

    if (node == null) {
        return 0;
    } else if (node.data == x && node.data == y) {
        return 1;
    } else if (node.data >= x && node.data <= y) {
        return 1 + nodesWithInRange(node.left, x, y) + nodesWithInRange(node.right, x, y);
    } else if (node.data > x && node.data > y) {
        return nodesWithInRange(node.left, x, y);
    } else {
        return nodesWithInRange(node.right, x, y);
    }
    

时间复杂度:-O(登录)+ O(K)

K是x和y之间的元素数。

这不是很理想,但是如果您不想修改二叉树节点的定义,那就很好了。

答案 3 :(得分:-1)

想法很简单。

  1. 从root开始遍历BST。
  2. 对于每个节点,检查它是否在范围内。 如果它在范围内则计算++。并为它的两个孩子重复。
  3. 如果当前节点小于范围的低值,则为正确的孩子重复,否则为左孩子重复。
  4. 时间复杂度为O(height + number of nodes in range) ..

    对于你的问题,为什么它不是O(n)

    因为我们没有遍历整个树,即树中节点的数量。我们只是根据父母的数据遍历所需的子树。

    伪代码

    int findCountInRange(Node root, int a, int b){
    
        if(root==null)
           return 0;
        if(root->data <= a && root->data >= b)
             return 1 + findCountInRange(root->left, a, b)+findCountInRange(root->right, a, b); 
        else if(root->data < low)
             return findCountInRange(root->right, a, b);
        else 
             return findCountInRange(root->left, a, b);
    
    }