algorithm - 获取二叉搜索树的间隔与排序数组一样快

标签 algorithm performance data-structures

目前我正在为我的大学项目用 Java 实现 BST。正如我们所知,BST 在平衡树中搜索复杂度为 O(log n) 的 单个 单元时非常好。

但是如何在值ab之间进行查找呢? (a < b)

假设我有这棵树

│               ┌── 125
│           ┌── 122
│           │   └── 120
│       ┌── 117
│       │   │   ┌── 113
│       │   └── 112
│       │       └── 108
│   ┌── 86
│   │   │   ┌── 85
│   │   └── 72
└── 59
    │           ┌── 56
    │       ┌── 52
    │   ┌── 47
    │   │   │   ┌── 43
    │   │   └── 39
    │   │       │   ┌── 38
    │   │       └── 36
    └── 28
        │       ┌── 18
        │   ┌── 15
        └── 2
            └── 1

我想创建一个方法 range(a,b) 以返回 ab 之间的值(包括在内)。 (注意:ab 在树中不是必需的!)

例如:range(53,112) 将返回 56,59,72,85,86,108,112

这是我的伪代码

/* recursive method */
range(a,b)
    range(a,b,root);

/* helper method */
range(a,b,node)
    if (a <= node.value <= b)
        if (node.left != null) and (node.value != a)
            range(a,b,node.left)

        print node.value

        if (node.right != null) and (node.value != b)
            range(a,b,node.right)

    else if node.value < a
        if (node.right != null)
            range(a,b,node.right)

    else // node.value > b
        if (node.left != null)
            range(a,b,node.left)

但是我觉得我的方法比较慢。

例如,在一个排序数组中,我们要对ab进行二分查找,得到它们各自的索引。之后,我们从 a 的索引迭代到 b 的索引。

BST 在搜索多个值时确实会执行得更慢吗?是否可以改进我的算法使其与排序数组一样快?

最佳答案

根据返回结果的方式,排序数组可能具有无需在任何地方复制结果的巨大优势。与将范围的另一个副本放入另一个缓冲区相比,仅将指针+长度 View 返回到数组中要快得多并且对缓存更友好。一棵树总是必须从树中复制元素。即使您确实需要副本(修改或其他),memcpy 也比走树快得多。

如果您可以在遍历树的同时进行处理(就像您使用 print 所做的那样),这就不是问题。

我似乎总是在谷歌搜索之前写下答案。结果是 trees to answer range queries are a thing .显然,它通常用于 2D 或 3D 范围(例如,每个点都有 x 和 y 坐标),而排序数组无法做到这一点。我认为这是因为即使它尽可能高效,它也没有将指针+长度窗口返回到排序数组中那么高效!

我不会从维基百科复制/粘贴整个算法,只是聪明的想法:

To report the points that lie in the interval [x1, x2], we start by searching for x1 and x2. At some vertex in the tree, the search paths to x1 and x2 will diverge

这就是您如何有效地检测您知道将在您的范围内的整个子树的方法,有关详细信息,请参阅维基百科和/或谷歌“树范围查询”。


我在谷歌搜索前的观察是,您可以避免比较,而只需遍历一些子树。在您的示例中,保证 86 的左子树都在范围内,因为我们知道它们都是 >59 和 <86,这比 [a. .b]。我没有想到一种方法来寻找这种特殊情况,这种情况可能不会比节省的开销更多。

关于algorithm - 获取二叉搜索树的间隔与排序数组一样快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32303154/

相关文章:

javascript - 从js“for”循环中的双计数器获得性能提升?

algorithm - 是否有任何好的算法来检测停止向服务器发送心跳的客户端?

algorithm - 使用 do While 循环反转 LinkedList

算法帮助 : Calculate binary possibilities whilst ignoring zero bits

algorithm - 占用边的最短路径查找算法

python - 有没有更快的方法来做到这一点? (python 推特位置)

algorithm - 动态规划任务/计数问题

performance - Go - 在用于负载测试的高性能 http 客户端中,如何阻止/忽略所有 cookie?

python - 在 OpenPYXL 中运行 50k 行 Excel 文件的最快方法

mysql - 在MySQL数据库中获取链表