Arrays 为什么要使用数组来实现;列表“;而不是哈希表?

Arrays 为什么要使用数组来实现;列表“;而不是哈希表?,arrays,language-agnostic,list,data-structures,hashtable,Arrays,Language Agnostic,List,Data Structures,Hashtable,考虑数组和哈希表,其中键只是列表的整数索引 它们的平均大小写插入、查找和删除big-O界限都是O(1)常量时间。我知道,在使用数组的缓存局部性方面,您可能会获得一些低级别的胜利,哈希表操作的开销很小(大部分是恒定的),但哈希表免费为您提供稀疏性,这在某些应用程序中是一个巨大的胜利 我还缺少什么其他重要的(或小的)对比 上下文:在面试编程候选人时,我有时会就此展开讨论。通常情况下,上下文是“如何在JS VM内部实现Javascript数组类型?”对于密集的数据,我支持本机数组,但我希望有更好的推理

考虑数组和哈希表,其中键只是列表的整数索引

它们的平均大小写插入、查找和删除big-O界限都是
O(1)
常量时间。我知道,在使用数组的缓存局部性方面,您可能会获得一些低级别的胜利,哈希表操作的开销很小(大部分是恒定的),但哈希表免费为您提供稀疏性,这在某些应用程序中是一个巨大的胜利

我还缺少什么其他重要的(或小的)对比


上下文:在面试编程候选人时,我有时会就此展开讨论。通常情况下,上下文是“如何在JS VM内部实现Javascript数组类型?”对于密集的数据,我支持本机数组,但我希望有更好的推理,而不是“看起来不太像杀伤力过大”的直觉。因为列表通常是有序的,而哈希表则不是。在向列表中添加元素并希望顺序保持一致的上下文中,哈希表不保证返回的顺序,而数组保留顺序。

因为哈希函数不是自由的。线性因素很重要。最坏情况下的时间很重要。数一数指令


对于您所引用的特定情况,即Javascript的底层实现,可能会有很多其他开销来消除这些问题。尽管如此,如果有人试图用简单的数字键来做一些数学上的事情,从而真正地打击数组,那么数组一定会更好。

数组是jsut,是哈希表的一种特例,其中哈希函数非常简单

f(x) := x;
所使用的模与数据字大小(因此数组大小)相同

如果不允许非唯一值,则不需要“下一个”指针,瞧,我们有一个数组


由于没有复杂的散列函数和模计算,这是非常快的,但仅在阵列可以保持较小时才适用(具有大量空位的非常大的阵列会浪费内存资源,并可能引发诸如交换/转储到磁盘之类的讨厌事情)当你从想要实现Javascript伪数组行为的人的角度来看它时,你是对的,哈希表是更好的实现方法,特别是因为Javascript数组没有固定的长度,需要能够容纳任何索引的条目。Javascript中的数组看起来像数组,但行为更像哈希表

但是,在一种更接近机器的语言中,对于可以高效存储在数组中的数据,使用真实数组的性能和空间优势是非常值得注意的,特别是因为使用哈希表的好处非常有限,仅限于稀疏数组,而稀疏数组不是您想要或应该使用数组的。实际上,使用具有整数键的哈希表可以更好地实现这一点

在所有情况下,数组的插入、查找和删除也是O(1),但常数O远低于哈希表(这不仅仅是因为缓存位置)。而且数组每个条目需要更少的空间。如果您希望以以下条目相应地更改其索引的方式删除和插入条目,则需要移动的条目数将是O(n),而哈希表也将是O(n),这样做又会带来更高的常量开销。这类操作最好使用链表。此外,增加一个数组比增加一个哈希表的成本要低,因为哈希表可能需要重新刷新它的所有条目


所有不同的收集类型都有各自的优缺点。这就是为什么有这么多的手机在使用。

谢谢tvanfosson。我更新了这个问题——我意识到一开始我并不清楚:我假设表中的键只是“列表”的整数索引,这意味着如果您通过整数“索引”访问对象,“顺序被保留”。我听说过的任何有效哈希表都不是这样的。@B argulies:当然,通过哈希桶进行抽象枚举是正确的。但是,如果我所有的键都表示列表中的索引,我可以在已知的“键”范围内为编写一个循环,并从我放入的索引中提取正确的值。@Ben-也许我遗漏了一些东西,但你不需要为每个整数设置一个bucket来实现这一点吗?如果在同一个bucket中有多个整数散列,则不能保留顺序。如果每个bucket有一个整数,那么这与稀疏填充的数组有何不同?假设bucket的数量和哈希算法是特定于实现的。但是,假设您有一些
put(key,obj)
操作和
get(key)
操作,您可以使用get操作对索引进行迭代,并增加键的索引。(答案可能是“所有的魔力都在这个特定于实现的部分中”。)看待它的有趣方式。谢谢好的,所以基本上,除了我所理解的之外,没有其他明显的区别——实际上,在这个场景中,哈希表是一个数组,具有更大的开销和自由稀疏性,在某种程度上,它更适合您的数据/场景。