C++ 二叉搜索树中的质量提取

C++ 二叉搜索树中的质量提取,c++,binary-tree,binary-search-tree,C++,Binary Tree,Binary Search Tree,在二元搜索树中,有没有有效的方法来查找少于一个元素的所有元素的数量?我一直在尝试在C++中找到一个过程或实现,但是我一直没能做到。所以说你有: 8 / \ 3 10 / \ \ 1 6 14 如果你想找到少于10个的节点,你可以得到4个 如果您使用std::map或std::set作为您的BST,则可以将成员函数与以下组合使用: 否则,您可以使用函数,但它只适用于平面容器(std::vector),因为它假定容器实现随机访问

在二元搜索树中,有没有有效的方法来查找少于一个元素的所有元素的数量?我一直在尝试在C++中找到一个过程或实现,但是我一直没能做到。所以说你有:

      8
    /   \
   3     10
  / \      \
 1   6      14
如果你想找到少于10个的节点,你可以得到4个

  • 如果您使用
    std::map
    std::set
    作为您的BST,则可以将成员函数与以下组合使用:

  • 否则,您可以使用函数,但它只适用于平面容器(
    std::vector
    ),因为它假定容器实现随机访问迭代器

    auto count = std::distance(
        bst.begin(), std::lower_bound(bst.begin(), bst.end(), target));
    

  • 如果您知道给定节点下面有多少个节点(在恒定时间内),只需执行以下操作:

    int BinarySearchTree::countLessThan(const Node *n, const T &value) const {
        if (n->value >= value) {
            // The value has to be in the left sub-tree, so continue searching there:
            if (n->left)
                return countLessThan(n->left, value);
            else
                return 0;
        } else {
            // The value has to be in the right sub-tree, so continue searching there
            // but include the whole left sub-tree and myself:
            int count = 1;
            if (n->left)
                count += n->left->count();
            if (n->right)
                count += countLessThan(n->right, value);
            return count;
        }
    }
    
    在根节点上启动算法:

    int BinarySearchTree::countLessThan(const T &value) const {
        countLessThan(root, value);
    }
    
    这里可以看到一个活生生的例子:

    它在以下树上运行(我交换了14和10,因此10可以是14的左子项。这是因为我的快速脏BST实现只允许右子项(如果已经有左子项):


    您可以这样做:

    int res = countLessThan(root, value, 0); // res is your answer
    
    然后执行以下操作:

    int BTree::countLessThan(node *currNode, int value, int count)
    {            
            if(currNode->left != NULL)
                    count = countLessThan(currNode->left, value, count);
    
            if(currNode->value >= value)
                    return count;
            count++;
    
            if(currNode->right != NULL)
                    count = countLessThan(currNode->right, value, count);
    
           return count;
    
    }
    

    根据二进制堆的实现情况,这是不可能的。@leems:为什么不可能呢。使用标准算法似乎是一个非常合理的答案。它假设二叉树已经实现了迭代器(不是大多数的C++容器都有迭代器的不合理假设(并且STD::SET有迭代器,并且最有可能作为二进制树实现)).@Alex B:二叉树不太可能有随机访问迭代器。@Leems:如果可以使用std::set,为什么要实现BST!无论如何,我想问题在于学习数据结构。因此,他不应该使用现有的数据结构来解决99%的问题。如果他只需要一个BST,他会在互联网上找到足够多的免费实现。静态变量?这很容易出错,但事实并非如此。(这意味着:函数的两个并行执行相互影响。)类使用静态变量来计算元素。因此,即使程序员使用不同的BST,两者都使用相同的静态变量。代码不返回要在代码中使用的头中写入静态变量的
    元素数。用户对此没有控制权。因此,在任何场景中,不同线程都会使用相同的变量。这甚至与BSP没有任何关系。@Telkitty:你为什么认为程序员不是白痴。更不用说他们知道一个程序的整个代码库(不太可能,大多数应用程序都足够大,以至于团队可以构建它(因此知道在所有情况下搜索树的时间是不合理的))。你应该在写不能被破解的代码。不是只有在使用不当的情况下才会被破坏的代码。@Telkitty:如果你在面试中写这篇文章,你就得不到这份工作。如果你写这篇文章作为作业的结果,你会得到E。简单是最好的。但你并没有让事情变得更简单,只是让事情变得更糟。如果你要费心回答这个问题,花点时间让它成为一段可用的代码(再加上几个额外的参数,它就不会像我说的那样需要实现访问者模式了)。不要搜索。思考和编码。你知道怎么穿过一棵树吗?这就足够了。我想知道你为什么用
    if-else
    而不是
    ?:
    。这将使不可读性更加一致。@Abyx:)我必须说:我的代码开始在表达式中有更少的分支,所以它是可读的。经过几次编辑,它变得越来越难看。我现在把它清理干净了。
    int res = countLessThan(root, value, 0); // res is your answer
    
    int BTree::countLessThan(node *currNode, int value, int count)
    {            
            if(currNode->left != NULL)
                    count = countLessThan(currNode->left, value, count);
    
            if(currNode->value >= value)
                    return count;
            count++;
    
            if(currNode->right != NULL)
                    count = countLessThan(currNode->right, value, count);
    
           return count;
    
    }