【问题标题】:What prevents Van Emde Boas trees from being more popular in real-world applications?是什么阻止了 Van Emde Boas 树在实际应用中更受欢迎?
【发布时间】:2014-01-19 16:51:52
【问题描述】:

我们知道平衡树在 O(log n) 时间内执行插入、删除和搜索,示例包括

  • 红黑
  • AVL
  • 展开
  • B 树(及其变体)。

但是,当键是某个有限范围内的整数时,可以使用 Van Emde Boas 树将这些操作降低到 O(log(log n)) 时间,即指数级优于 AVL 或 RB 树。 嗯,这实际上是许多现实世界应用程序的情况。

我看到很多这样的应用程序。 我想引用的一个是数据库,创建索引基本上涉及在哈希或 B*-树之间进行选择。 如果实现了 Van Emde Boas 树,它将提供这两个选项之间的折中,理论上可以改善许多查询优化问题。

为什么 Van Emde Boas 树没有像 Red-Black 或 B-tree 那样被广泛使用

  • 这不是什么新鲜事(它是 1975 年发明的)
  • 易于实施
  • 比其他树快得多

关于它的考虑是什么?

【问题讨论】:

  • 可能是因为大量的数据库键不是有限范围内的整数? :-) 如果你知道有限的范围,你通常可以制作一个非常有效的哈希函数,可能是一个完美的哈希,甚至可能是一个完美的最小哈希,从而使树结构变得无关紧要。
  • @paxdiablo SQL 数据库中的主键几乎总是(最初是连续的)一些大但有限范围的整数(例如 64 位)。确实可以为这些键设计非常有效的哈希表,但是找到一个完美(更不用说最小完美)哈希需要知道 full 组键,需要找到一个新的完美哈希函数并重新-散列整个表每次添加或删除一个键。这是一个更狭窄的用例,因为它只适用于 static 键集。

标签: data-structures van-emde-boas-trees


【解决方案1】:

渐近复杂度有时会产生误导。在Van Emde Boas tree 的情况下,常数非常大see here。我引用:

However, for small trees the overhead associated with vEB trees
is enormous: on the order of 2^(m/2)

还有其他情况,存在具有更好复杂性的算法,但只有在输入如此之大以致在实践中几乎从未使用过它时才会变得更好,例如线性时间静态 RMQ。

【讨论】:

  • 在另一种情况下,基数排序似乎在实际应用中存在同样的开销问题。
  • @CássioJandirPagnoncelli 是的。基数排序在你的值的位数的顺序上有一个常数因子,在大多数实际情况下,它甚至比你要排序的元素数量的对数还要多。
  • 另一个很好的例子是整数乘法算法。很少有用于不同范围的,甚至很少有根本没有使用(可能还没有),因为在输入如此大的输入时存在实际的实际问题,以至于它们将开始克服更差的 Big O 对应部件.
  • 对 vEB 表使用哈希表可以使 vEB 比二叉搜索树更有效,即使是小树。
  • 当对 vEB 表使用哈希表时,占用的空间是 O(n) 而不是 O(M) 或 O(2^m)。
【解决方案2】:

其中一个原因是复杂性不是根据您存储的集合的大小来定义的,而是根据值域的大小来定义的。 另一个区别是键不能是具有比较操作的任意类型,但必须是整数。 您不应将 vEB 视为 BST 的替代品,而应将其视为数组的替代品。 数组具有 O(1) 存储和查找以整数为键的对象的成本。 vEB 提供 O(log log M),其中 M 是您的值的大小。 现在,您看到 vEB 在查找和存储方面并不比常规数组好,但它提供 O(1) 最小、最大操作和 O(log log M) prev next 关键操作,而数组没有。 值得一提的是,vEB 树的布局有一个特性,可以创建缓存遗忘树,这是现代 CS 中更有趣的发展。

http://erikdemaine.org/papers/BRICS2002/paper.pdf

【讨论】:

  • 数组不提供 O(1) prev/next,因为它们具有恒定时间随机访问吗?如果您知道当前项目的位置,那么您可以在恒定时间内获取下一个/上一个。
  • 我们正在讨论数组中的集合表示,如果 x 在集合中,则 a[x] = true,否则为 false。所以你有不断的插入和成员资格测试,但是线性的下一个/上一个。如果您只是按升序列出数组中的元素,则您有 O(log N) 成员资格测试(通过二进制搜索)、O(n) instert(保持排序顺序)和 O(1) prev/next。跨度>
  • @quikchange by prev/next 我的意思是由类型的顺序定义的前任和后继,而不是数据布局中的前一个下一个。
  • @quikchange 仅当您的数组已满时。如果您的数组包含 4 个元素,例如 [1, 10, 100, 1000] 并且长度为 1000,从 1000 移动到其上一个 (100) 不是 O(1) 而是 O(N)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
  • 2016-12-10
  • 2017-08-04
  • 2020-10-25
  • 1970-01-01
相关资源
最近更新 更多