为什么HashMap中查找是O(1),即固定的时间?(Why hashmap lookup is O

2019-07-21 20:31发布

如果我们从Java的角度看那么我们可以说,HashMap中查找需要一定的时间。 但是关于内部实现什么? 它仍然必须通过搜索特定的桶(用于匹配的哪个键的散列码)对不同的匹配keys.Then为什么我们说,HashMap中查找需要一定的时间? 请解释。

Answer 1:

根据所使用的散列函数中,适当的假设,我们可以说,哈希表查找需要预期的 O(1)时间(假设你使用像线性探测或链哈希标准的散列方案)。 这意味着, 平均而言 ,工作的一个哈希表不会执行查找量最多为某一常数。

直观地说,如果你有一个“好的”散列函数,你所期望的元素将被分配或多或少的均匀分布在整个哈希表,这意味着每个桶中元素的个数将接近除以数的元素个数水桶。 如果哈希表的实现保持这个数低(比如,通过增加更多的水桶每个元素的水桶之比超过某个常数时间),即得到所做的工作则预计金额最终被工作选择哪个桶的一些基线量应该进行扫描,然后做“初生牛犊”的工作看着那里的元素,因为预期只会出现在该区块的元素的常数。

这并不意味着哈希表保证了O(1)行为。 事实上,在最坏的情况下,哈希方案会变质和所有元件将在一个桶中结束,使得查找需要在最坏情况下的时间Θ(n)中。 这就是为什么它设计一个良好的散列函数是很重要的。

欲了解更多信息,您可能需要阅读的算法教科书,看看为什么哈希表,以便有效地支持查找的正式推导。 这通常包括作为算法和数据结构一个典型的大学课程的一部分,有很多很好的资源联机。

有趣的事实:有某些种类哈希表(杜鹃哈希表,动态完美哈希表),其中最坏情况下查找时间对元件的是O(1)。 这些哈希表通过确保每个元素只能在几个固定的位置之一,有时插入元素周围争先恐后地试图使一切Fit两种工作。

希望这可以帮助!



Answer 2:

最关键的是在文档这样的说法:

如果很多映射关系将被存放在一个HashMap实例,具有足够大的容量创建它将使映射不是让作为生长所需的表就执行自动再散列更有效地存储。

加载因子是哈希表是如何充分允许获得之前它的容量自动增加的措施。 当在散列表中的条目的数量超过了负载因数和电流容量的乘积,哈希表被重新散列(即,内部数据结构被重建),使得哈希表具有桶的大约两倍。

http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html

如果超过了客座率的内部桶结构实际上将被重建,允许的摊余成本 获得 ,并为O(1)。

请注意,如果内部结构重建时,引入了性能损失很可能是O(N),因此相当多的获得和之前的摊余成本 (1)再次接近O可能会被要求 。 因此,合理地规划初始容量和负载因子,使你既没有浪费的空间,也引发内部结构的重建不可避免。



Answer 3:

为了跟进templatetypedef的意见,以及:

哈希表的恒定时间实现可以是一个HashMap,通过它可以实现表示在水桶中是否存在特定元素的布尔数组列表。 但是,如果要实现你的HashMap中的链表,在最坏的情况下可能需要您经历的每一个桶,并且具有通过列表的末端穿越。



文章来源: Why hashmap lookup is O(1) i.e. constant time?