考虑一个数组和一个哈希表,在哈希表中,键只是一个列表的整数索引。
它们的平均大小写插入、查找和删除大O界限都是O(1)
常量时间。我知道使用数组可能会在缓存局部性方面获得一些低级别的胜利,哈希表操作有一个边际(几乎是恒定的)开销,但哈希表可以免费获得稀疏性,这在某些应用程序中是一个很大的胜利。
我还遗漏了哪些重要的(或小的)对比?
上下文:在面试编程候选人时,我有时会对此进行讨论。通常上下文是“如何在JS中实现Javascript数组类型?”对于密集打包的数据,我支持原生数组,但我希望有更好的推理,而不是“它看起来不像是过度杀伤力”的直觉。
发布于 2010-02-16 10:31:50
数组是哈希表的一个特例,其中哈希函数非常简单
f(x) := x;
并且所使用的模数与数据字大小(以及因此数组大小)相同。
如果你不允许非唯一的值,你就不需要"next“指针,瞧,我们有一个数组。
由于没有复杂的哈希函数和模运算,这是非常快的,但只有当数组可以保持小的时候才适用(具有大量空位的非常大的数组浪费内存资源,并可能触发交换/回收到磁盘的麻烦事情)。
发布于 2010-02-16 16:37:08
当你从一个想要实现Javascript的伪数组行为的人的角度来看,你是对的,哈希表是做这件事的更好的方法,特别是。因为Javascript数组没有固定长度,并且需要能够容纳任何索引处的条目。Javascript中的数组看起来像数组,但行为更像哈希表。
但是在一种更接近机器的语言中,对于可以有效地存储在数组中的数据,使用实数组的性能和空间优势是相当值得注意的,特别是因为使用哈希表的好处仅限于稀疏数组,这不是您将使用或应该使用的数组。实际上,使用具有整数键的哈希表可以更好地完成此任务。
在所有情况下,数组的插入、查找和删除也是O(1),但它的常数O比哈希表低得多(这不仅仅是因为缓存的局部性)。并且数组每个条目所需的空间更少。如果您希望删除和插入条目的方式使后面的条目相应地更改它们的索引,那么它将是O(n),其中n是需要移动的条目的数量,但是对于哈希表来说,这样做也是O(n),并且具有更高的常量开销。这是一种你最好使用链表的操作。此外,增加一个数组比增加一个可能需要重新计算所有条目的哈希表的成本更低。
所有不同的集合类型都有其特定的优点和缺点。这就是为什么有这么多人在使用它们。
发布于 2010-02-15 16:32:32
因为列表通常是有序的,而哈希表则不是。在将元素添加到列表中并期望顺序保持一致的上下文中,哈希表不能保证您返回的顺序,而数组保留了顺序。
https://stackoverflow.com/questions/2267331
复制相似问题