hash表的出現主要是爲了對內存中數據的快速、隨機的訪問。它主要有三個關鍵點:Hash表的大小、Hash函數、衝突的解決。
這裏首先談談第一點:Hash表的大小。
Hash表的大小一般是定長的,如果太大,則浪費空間,如果太小,衝突發生的概率變大,體現不出效率。所以,選擇合適的Hash表的大小是Hash表性能的關鍵。
對於Hash表大小的選擇通常會考慮兩點:
第一,確保Hash表的大小是一個素數。常識告訴我們,當除以一個素數時,會產生最分散的餘數,可能最糟糕的除法是除以2的倍數,因爲這隻會屏蔽被除數中的位。由於我們通常使用表的大小對hash函數的結果進行模運算,如果表的大小是一個素數,就可以獲得最佳的結果。
第二,創建大小合理的hash表。這就涉及到hash表的一個概念:裝填因子。設裝填因子爲a,則:
a=表中記錄數/hash表表長
通常,我們關注的是使hash表的平均查找長度最小,而平均查找長度是裝填因子的函數,而不是表長n的函數。a的取值越小,產生衝突的機會就越小,但如果a取值過小,則會造成較大的空間浪費,通常,只要a的取值合適,hash表的平均查找長度就是一個常數,即hash表的平均查找長度爲O(1)。
當然,根據不同的數據量,會有不同的哈希表的大小。對於數據量時多時少的應用,最好的設計是使用動態可變尺寸的哈希表,那麼如果你發現哈希表尺寸太小了,比如其中的元素是哈希表尺寸的2倍時,我們就需要擴大哈希表尺寸,一般是擴大一倍。
下面是哈希表尺寸大小的可能取值:
17, 37, 79, 163, 331,
673, 1361, 2729, 5471, 10949,
21911, 43853, 87719, 175447, 350899,
701819, 1403641, 2807303, 5614657, 11229331,
22458671, 44917381, 89834777, 179669557, 359339171,
718678369, 1437356741, 2147483647