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語言描述) 第三版

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM