Performance 哈希表-为什么它比数组快?

Performance 哈希表-为什么它比数组快?,performance,algorithm,hash,hashtable,Performance,Algorithm,Hash,Hashtable,如果每个元素都有一个键,但不知道该元素在数组中的索引,则哈希表的性能优于数组(O(1)vs O(n)) 为什么呢?我的意思是:我有一把钥匙,我把它弄碎了。。我有杂烩。。算法不应该将这个散列与每个元素的散列进行比较吗?我认为内存配置背后有一些技巧,不是吗?哈希表有点复杂。他们根据散列%some值将元素放入不同的桶中。在理想的情况下,每个桶只装很少的物品,空桶也不多 一旦知道了密钥,就可以计算散列。根据散列,您知道要查找哪个bucket。如上所述,每个桶中的物品数量应该相对较少 哈希表在内部发挥了巨

如果每个元素都有一个键,但不知道该元素在数组中的索引,则哈希表的性能优于数组(O(1)vs O(n))


为什么呢?我的意思是:我有一把钥匙,我把它弄碎了。。我有杂烩。。算法不应该将这个散列与每个元素的散列进行比较吗?我认为内存配置背后有一些技巧,不是吗?

哈希表有点复杂。他们根据散列%some值将元素放入不同的桶中。在理想的情况下,每个桶只装很少的物品,空桶也不多

一旦知道了密钥,就可以计算散列。根据散列,您知道要查找哪个bucket。如上所述,每个桶中的物品数量应该相对较少

哈希表在内部发挥了巨大的作用,以确保存储桶尽可能小,同时不会为空存储桶消耗太多内存。另外,很大程度上取决于key->hash函数的质量


Wikipedia提供了。

数组:如果你知道值,你必须平均搜索一半的值(除非排序)才能找到它的位置


带散列:根据值生成位置。因此,再次给定该值,可以计算插入时计算的哈希值。有时,多个值会导致相同的散列,因此在实践中,每个“位置”本身就是散列到该位置的所有值的数组(或链表)。在这种情况下,只需要搜索这个小得多的数组(除非它是一个糟糕的散列)。

我想你已经回答了你自己的问题。“算法不应该将这个散列与每个元素的散列进行比较吗?”。当它不知道你要搜索的内容的索引位置时,它就是这样做的。它会比较每个元素以找到您要查找的元素:

例如,假设您正在字符串数组中查找名为“Car”的项。您需要检查每个项目,并检查item.Hash()==“Car”.Hash()以找出您正在查找的项目。显然,它在搜索时不总是使用散列,但这个例子是正确的。然后你有一个哈希表。哈希表所做的是创建一个稀疏数组,或者有时像上面提到的那样创建一个桶数组。然后它使用“Car”.Hash()来推断“Car”项在稀疏数组中的实际位置。这意味着它不必搜索整个数组来查找您的项目

如果每个元素都有一个键,但我不知道 将元素索引到数组中,哈希表的性能优于 数组(O(1)vs O(n))

哈希表搜索在平均情况下执行O(1)。在最坏的情况下,哈希表搜索执行O(n):当发生冲突时,哈希函数总是返回相同的插槽。人们可能会认为“这是一个遥远的情况”,但一个好的分析应该考虑它。在这种情况下,您应该遍历所有元素,如数组或链表(O(n))中的元素

为什么呢?我的意思是:我有一把钥匙,我把它弄碎了。。我有杂烩。。 算法不应该将这个散列与每个元素的散列进行比较吗 搞砸我想在记忆处理的背后有一些技巧,不是吗 是吗

你有一把钥匙,你把它散列。。您有一个hash:元素所在的哈希表的索引(如果它以前被定位过)。此时,您可以访问O(1)中的哈希表记录。如果荷载系数很小,则不太可能看到多个构件。因此,您看到的第一个元素应该是您正在查找的元素。否则,如果有多个元素,则必须将在该位置找到的元素与正在查找的元素进行比较。在这种情况下,有O(1)+O(元素的数量)

在平均情况下,哈希表搜索复杂度为O(1)+O(加载因子)=O(1+加载因子)

记住,在最坏的情况下,荷载系数=n。因此,在最坏的情况下,搜索复杂度为O(n)

我不知道你说的“记忆处置背后的诡计”是什么意思。在某些观点下,哈希表(其结构和通过链接解决的冲突)可以被认为是一个“聪明的把戏”


当然,哈希表分析结果可以通过数学证明。

哈希表不必比较哈希表中的每个元素。它将根据密钥计算hashcode。例如,如果键是4,那么hashcode可能是-4*x*y。现在指针确切地知道要拾取哪个元素

然而,如果它是一个数组,它必须遍历整个数组来搜索这个元素

为什么[哈希表按键查找比数组(O(1)vs O(n))要好]?我的意思是:我有一把钥匙,我把它弄碎了。。我有杂烩。。算法不应该将这个散列与每个元素的散列进行比较吗?我认为在记忆处理的背后有一些技巧,不是吗

一旦你有了散列,它可以让你计算一个“理想的”或预期的位置在桶数组中:通常:

理想存储桶=哈希%num\u存储桶

问题是另一个值可能已经散列到该存储桶,在这种情况下,哈希表实现有两个主要选择:

1) 试试另一个水桶

2) 让几个不同的值“属于”一个bucket,可能是通过让bucket将指针放入一个值的链表中

对于被称为的实现1,您可以跳转到其他bucket:如果您发现了自己的价值,那就太好了;如果您找到了一个从未使用过的bucket,那么您可以在插入时将您的值存储在其中,或者您知道在搜索时将永远找不到您的值。如果遍历替代存储桶的方式最终多次搜索同一个存储桶,则搜索可能比O(n)更糟糕;例如,如果您使用理想的桶索引+1、然后是+4、然后是+9、然后是+16,依此类推-