渐进快速的具有低内存需求的关联数组

3

好的,tries数据结构已经存在了一段时间。一个典型的实现应该可以独立于数据集大小n,给出O(m)的查找、插入和删除操作,其中m是消息长度。然而,在最坏的情况下,相同的实现需要占用256个字节的输入字节。

其他数据结构,特别是哈希表,可以给你期望的O(m)查找、插入和删除操作,有些实现甚至提供常数时间的查找。然而,在最坏的情况下,这些例程要么不停止,要么花费O(nm)的时间。

问题是,是否存在一种数据结构,可以在保持与哈希表或搜索树相当的内存占用的同时,提供O(m)的查找、插入和删除时间?

可能适合说的是,我只关心最坏情况下的行为,无论是时间方面还是空间方面。


3
“do not halt”是什么意思?哪种哈希表算法不会停止运行? - Gabe
一些实现甚至提供常数查找时间 - 我从未听说过一个哈希表不这样做。 - Nick Johnson
Gabe:Cukoo哈希在插入时没有停止保证。Nick:我是指最坏情况下的常数时间。 - Luís Fernando Schultz Xavier
4个回答

4

您尝试过使用Patricia(别名critbit或Radix)树吗?我认为它们可以解决最坏情况下的空间问题。


基数 Trie 和普通 Trie 之间有什么区别? - Gabe
Patricia似乎是一个可行的替代方案。我将尝试推导/研究最坏情况。你有任何参考资料吗? - Luís Fernando Schultz Xavier
盖布:他们在边缘上使用字符串而不是字符,以避免扇出1节点。 - Luís Fernando Schultz Xavier
这里有一篇关于DJB(qmail的Dan Bernstein)对Patricia和crit-bit的看法的文章:http://www.imperialviolet.org/2008/09/29/critbit-trees.html我的默认模式是,如果DJB使用它,那么它可能非常好。我记得他宣布了一篇关于性能的论文,但我不知道是否已经发表了。 - Nordic Mainframe
非常感谢这个很棒的参考资料!我会寻找关于这种数据结构的分析。 - Luís Fernando Schultz Xavier

0

有一个被称为后缀数组的数据结构。我记不得这个领域的研究了,但我认为他们用这个数据结构已经非常接近O(m)的查找时间了,并且它比你通常使用的基于树的索引方法要紧凑得多。

Dan Gusfield的书是字符串算法的圣经。


后缀数组通常是静态的。 - Luís Fernando Schultz Xavier
抱歉,我不知道这是一个要求。 - San Jacinto

0

我认为有两个原因不必担心最坏情况:

  1. 在所有trie节点的总和中,您永远不会拥有比存储数据的总大小更多的活动分支。
  2. 节点大小成为问题的唯一时刻是如果您正在对您排序/存储的数据进行大量扇出。助记符就是其中的一个例子。如果您依赖trie作为压缩机制,那么哈希表对您也没有任何好处。

如果您需要压缩,并且您几乎没有共同的子序列,那么您需要设计一种基于数据特定形状而不是基于字符串通用假设的压缩算法。例如,在完全/高度填充的助记符数据集的情况下,跟踪数据中的“空洞”而不是填充数据的数据结构可能更有效。

话虽如此,如果您有适度的扇出,避免使用固定的trie节点大小可能会更好。您可以将trie的每个节点设置为哈希表。从小尺寸开始,随着元素的插入而增加。当每个哈希表由于增加而必须重新组织时,最坏情况的插入将是c * m,其中c是可能字符/唯一原子元素的数量。


点(1)是正确的,但对于点(2),我不感兴趣压缩,我的担忧是,正如你所指出的,许多低扇出节点可能会消耗大量空数组条目。我想要的是我的trie每插入一个字节时,它将具有的字/字节数的上限。它可以是4或8,但不是256 * 4 = 1K。而且我绝对不希望得到小于1的东西,也就是说,我不试图进行压缩。 - Luís Fernando Schultz Xavier

0
在我的经验中,有三种实现方式可以满足您的要求:

您可以在这里看到基准测试。它们与哈希表一样快,但内存需求更低,最坏情况下性能更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接