一尘不染

哈希表真的可以是O(1)吗?

algorithm

哈希表可以实现O(1)似乎是常识,但是这对我来说从来没有任何意义。有人可以解释一下吗?这是两种情况:

答: 该值是一个小于哈希表大小的整数。 因此,该值是其自己的哈希,因此没有哈希表。但是,如果有的话,它将是O(1),但效率仍然很低。

B. 您必须计算值的哈希值。
在这种情况下,对于要查找的数据大小,顺序为O(n)。在您执行O(n)工作后,查找可能是O(1),但在我眼中仍然是O(n)。

而且,除非您拥有完美的哈希表或大型哈希表,否则每个存储桶中可能有几项。因此,无论如何它都会演变成小的线性搜索。

我认为哈希表很棒,但除非得到理论上的支持,否则我不会获得O(1)的名称。

Wikipedia的有关哈希表文章始终引用恒定的查找时间,并且完全忽略了哈希函数的成本。这真的是公平的措施吗?


编辑: 总结一下我学到的东西:

  • 从技术上讲这是正确的,因为不需要散列函数使用键中的所有信息,因此可以是恒定时间,并且因为足够大的表可以使冲突降低到接近恒定时间。

  • 在实践中确实如此,因为随着时间的推移,只要选择哈希函数和表大小以最大程度地减少冲突,就可以解决问题,尽管这通常意味着不使用恒定时间哈希函数。


阅读 416

收藏
2020-07-28

共1个答案

一尘不染

这里有两个变量,m和n,其中m是输入的长度,n是哈希中的项数。

O(1)查询性能声明至少做出两个假设:

  • 您的对象在O(1)时间内可以相等。
  • 几乎没有哈希冲突。

如果对象的大小可变,并且相等性检查需要查看所有位,则性能将变为O(m)。但是,哈希函数不必为O(m)-可以为O(1)。与加密哈希不同,在字典中使用的哈希函数不必查看输入中的每一位即可计算哈希。实现可以随意查看固定位数。

对于足够多的项目,项目数将变得大于可能的散列数,然后您将发生碰撞,从而导致性能提高到O(1)以上,例如对于简单链表遍历(或O(n * m)如果两个假设都为假)。

在实践中,尽管O(1)声称在技术上是错误的,但在许多现实情况下,尤其是在上述假设成立的情况下, 大约 是正确的。

2020-07-28