通過hash函數將數據映射爲索引(下標),便於查找,在hash衝突做得好且數據較少的情況下可達到O(1)。
常用的hash函數有除留餘數法,線性探測,二次探測,開鏈法,在大部分情況下基本就是用開鏈法:
hash的負載因子:元素個數/hash表長度 一般控制在0.7 -0. 8
如何提高hash查找的效率
- 設置好的hash函數,衝突儘量少
- 空間換時間,增大表長
- STL使用素數表
- hash桶掛紅黑樹
hash表擴容
容量擴張(Expand)& 分攤轉移
Hash表中每次發現loadFactor到一定程度時(比如大於0.8),就開闢一個原來桶數組的兩倍空間(稱爲新桶數組),然後把原來的桶數組中元素所有轉移過來到新的桶數組中。注意這裏轉移是須要元素一個個又一次哈希到新桶中。
這樣的方法的缺點是,容量擴張是一次完畢的,期間要花非常長時間一次轉移hash表中的全部元素
Memcached的擴容條件是當表中元素個數超過Hash容量的1.5倍時就進行擴容,擴容過程由獨立的線程來完成,擴容過程中會採用2個Hash表,將老表中的數據通過Hash算法映射到新表中,每次移動的桶的數目可以配置,默認是每次移動老表中的1個桶。
這樣的策略就把第一個hash表全部元素的轉移分攤爲多次轉移,並且每次轉移的期望時間複雜度爲O(1)。
參考:深入理解hash
一致性hash,線性hash