• P2 哈希表之装载因子


          装载因子:load fator,散列表中关键字个数和散列表长度之比。她用于度量所有关键字填充哈希表后饱和的程度。

          重哈希:rehash,亦或再散列,当装载因子达到指定阈值时,散列表进行扩容的过程。

          由公式可知,装载因子越大,哈希表填满时所容纳的元素越多,空闲位置越少,好处是提高了空间利用率,但是增加了哈希碰撞的风险,降低了哈希表的性能。

    对于没有频繁插入和删除的静态数据而言,可以根据数据的特点和分布情况设计出符合这些数据的哈希函数,从而减少哈希碰撞。

          但是大部分情况下是动态数据,数据集合是频繁变动的,我们无法预知数据的个数,因此也无法事先申请一个足够大的 Hash表。随着数据加入,填入表中的元素个数增多,装载因子增大,当装载因子达到一定程度时,哈希碰撞便不可接受,因此我们无法根据数据的特征和分布情况设计出符合这些数据的 Hash函数,而是需要动态扩容,重新申请一个更大的 Hash表并将数据重新散列,存储到新的 Hash表中。

          如下图中的散列表,当装载因子达到阈值0.8时进行重哈希,使得装载因子变为0.4,并根据哈希函数把原来的数据存储到新的散列表中。

     

          当数据插入到 Hash表时,如果装载因子还未达到指定阈值,那么不需要重哈希,插入数据非常快,但如果装载因子达到了阈值,就需要首先重哈希,此时就会变得很慢。

          当数据需要从 Hash表中删除时,如果 Hash表已经经历过重哈希,随着数据的删除,空闲空间会越来越多。当程序对内存空间非常敏感时,可以设置当装载因子小于某个临界值时,启动动态缩容,让内容空间得到充分利用;当程序对内存空间不太敏感时,就不需要进行动态缩容处理。 

          发散思维,HashMap的装载因子为什么是0.75?经过前面的分析,基本上为什么是0.75的答案也就出来了,这是时间和空间的权衡。答案就在源码上,我们可以看看:

    As a general rule, the default load factor (.75) offers a good tradeoff between time and space costs. Higher values decrease the space overhead but increase the lookup cost (reflected in most of the operations of the HashMap class, including get and put). The expected number of entries in the map and its load factor should be taken into account when setting its initial capacity, so as to minimize the number of rehash operations. If the initial capacity is greater than the maximum number of entries divided by the load factor, no rehash operations will ever occur.

          大致意思就是说默认负载因子(0.75)在时间与空间成本之间提供了良好的权衡,并且尽量减少了重哈希次数。

    Reference

     

    https://cloud.tencent.com/developer/article/1493913

    https://baijiahao.baidu.com/s?id=1656137152537394906&wfr=spider&for=pc

    数据结构与算法分析(Java语言描述) 第三版

     

  • 相关阅读:
    06C++11线程池
    05C++11生产者消费者模式2
    04C++11生产者消费者模式
    03智能指针之shared_ptr
    洛谷P1262+Tarjan缩点
    洛谷P1147 连续自然数和
    洛谷P1970 花匠
    接下来的一些操作
    树状数组 代码(洛谷为例)
    洛谷P1576 最小花费
  • 原文地址:https://www.cnblogs.com/east7/p/12594259.html
Copyright © 2020-2023  润新知