哈希表和并排列表?

时间:2010-11-07 14:19:47

标签: language-agnostic linked-list hashtable

我需要一个有序的数据结构,但也提供快速随机访问和插入和删除。 Linkedlists是有序且快速插入和删除但它们提供慢速随机访问。 Hashtables提供快速随机访问,但不是有序的。

所以,将两者结合使用似乎很不错。在我当前的解决方案中,我的Hashtable包括列表的迭代器,List包含实际的项目。很好,很有效。好的,它需要双倍的内存,但这不是问题。

我听说有些树形结构也能做到这一点,但它们和这个解决方案一样快吗?

5 个答案:

答案 0 :(得分:3)

我知道最有效的树结构是Red Black Tree,并且它没有解决方案那么快,因为它对所有操作都有O(log n),而你的解决方案对某些解决方案有O(1),如果不是全部的话,运营。

如果内存不是问题,并且您确定您的解决方案是O(1),这意味着在结构中添加/删除/查找项目所需的时间与您拥有的项目数量无关,请选择它。

答案 1 :(得分:1)

Java实际上包含LinkedHashTable,它与您描述的数据结构类似。它有时会非常有用。

树结构也可以工作,看到它们可以在(O log n)时间内执行随机访问(以及大多数其他操作)。不如Hashtables(O 1)快,但除非您的数据库非常大,否则仍然很快。

树的唯一真正优势是您不需要事先决定容量。一些HashTable实现可以根据需要增加其容量,但只需将它们超出容量时将所有项目复制到一个新的更大的哈希表中,这非常慢。 (O n)

答案 2 :(得分:1)

您应该考虑Skip List,这是一个有序的链接列表,具有O(log n)访问时间。换句话说,你可以枚举它O(n)和索引/插入/删除是O(log n)。

答案 3 :(得分:1)

为此制作树木。最合适的是自我平衡树,例如 AVL tree Red Black tree 。如果您处理非常大的数据量,那么创建 B-tree (例如,它们用于文件系统)可能也很有用。

关于您的实施:根据您使用的数据量 HashTable实施,它可能比树更高效或更低效。例如。一些具有非常密集数据的哈希表可以不在O(1)中进行访问,而是在O(log n)或甚至O(n)中进行访问。还要记住,从数据计算哈希也需要一些时间,因此对于退出小数据量计算哈希的绝对时间可能更多用于在树中搜索它。

答案 4 :(得分:1)

你所做的几乎是正确的选择。

关于这一点很酷的是,通过使用双端双链表对现有地图实现添加排序实际上并没有改变其渐近复杂度,因为所有相关的列表操作(追加和删除)都有最差的 - Θ(1)的步骤复杂度。 (是的,删除也是Θ(1)。它通常是Θ(n)的原因是因为你必须先找到要删除的元素,即Θ(n),但实际上是删除本身是Θ(1)。在这种特殊情况下,你让地图进行查找,这类似于Θ(1)摊销最坏情况的步骤复杂度或Θ(log b n)最坏情况下的步骤复杂性,具体取决于所使用的地图实现的类型。)

例如,Ruby 1.9中的Hash类是一个有序映射,它至少在YARV和Rubinius中实现为嵌入到链表中的哈希表。

对于随机访问,树通常具有最差情况下的步骤复杂度Θ(log b n),而在最坏情况下(或Θ(n)),哈希表可能更差,但通常是摊销到Θ(1),前提是你没有搞砸哈希函数或调整大小函数。

[注意:我故意只讨论这里的渐近行为,即“无限大”集合。如果您的馆藏很小,那么只需选择具有最小常数因子的馆藏。]