哈希函數的構造不是越復雜越好,因為往往哈希函數越復雜,取得關鍵字地址所消耗的時間越長,可能對哈希法性能造成一定的影響,因此選取哈希函數的時候,應該多方面權衡,選擇合適的哈希函數(即不存在特別好與壞的哈希函數,需視情況而定)。
哈希函數有一個共同的性質,即哈希值應當以同等概率取其值域的每個值。
常用哈希函數構造方法:
(1)直接尋址法:取關鍵字或關鍵字的某個線性函數值作為散列地址,即 H(key) = key 或 H(key) = a * key + b,其中 a 和 b 為常數(這種散列函數叫自身函數)。
(2)數字分析法:分析一組數據,比如某班學生的出生年月日時發現出生年月日的前幾位數字大體相同,這樣的話,沖突的幾率會很大,但是發現年月日的后幾位表示月份和具體日期的數字差別較大,如果用后幾位構成散列地址,則沖突的幾率會明顯降低。因此數字分析法是找出數字的規律,盡可能利用這些數字構造沖突幾率低的散列地址。
(3)平方取中法:先通過求關鍵字的平方值擴大相近的差別,然后根據表長度取中間的幾位數作為散列函數值。又因為一個乘積的中間幾位數和乘數的每一位都相關,所以由此產生的散列地址較為均勻。
(4)除余法:該方法是最為簡單常用的一種方法。它是以表長 m 來除關鍵字,取其余數作為散列地址,即 H(key) = key % m。該方法的關鍵是選取 m。選取的 m 應使得散列函數盡可能與關鍵字的各位相關。m 最好為素數。
(5)相乘取整法:該方法包括兩個步驟,首先用關鍵字 key 乘上某個常數 A(0 < A < 1),並抽取出 key.A 的小數部分;然后用 m 乘以該小數后取整。
常見哈希沖突解決辦法:
(1)開放地址法
(2)線性探測法
(3)鏈地址法(拉鏈法)
(4)二次探測法
(5)偽隨機探測法
(6)再散列(雙重散列,多重散列)
(7)建立一個公共溢出區