好的散列函數要求:(1)計算簡單,至少散列函數的計算時間不應該超過其他查找技術與關鍵字比較的時間;(2)計算出的散列地址分布均勻,這樣可以保證存儲空間的有效利用,並減少為處理沖突而耗費的時間。
1. 直接定址法
取關鍵字或關鍵字的某個線性函數值為散列地址。即H(key)=key或H(key) = a·key + b,其中a和b為常數(這種散列函數叫做自身函數)。
2. 數字分析法
假設某公司的員工登記表以員工的手機號作為關鍵字。手機號一共11位。前3位是接入號,對應不同運營商的子品牌;中間4位表示歸屬地;最后4位是用戶號。不同手機號前7位相同的可能性很大,所以可以選擇后4位作為散列地址,或者對后4位反轉(1234 -> 4321)、循環右移(1234 -> 4123)、循環左移等等之后作為散列地址。
數字分析法通常適合處理關鍵字位數比較大的情況,如果事先知道關鍵字的分布且關鍵字的若干位分布比較均勻,就可以考慮這個方法。
3. 平方取中法
假設關鍵字是1234、平方之后是1522756、再抽取中間3位227,用作散列地址。平方取中法比較適合於不知道關鍵字的分布,而位數又不是很大的情況。
4. 折疊法
將關鍵字從左到右分割成位數相等的幾部分,最后一部分位數不夠時可以短些,然后將這幾部分疊加求和,並按散列表表長,取后幾位作為散列地址。
比如關鍵字是9876543210,散列表表長是3位,將其分為四組,然后疊加求和:987 + 654 + 321 + 0 = 1962,取后3位962作為散列地址。
折疊法事先不需要知道關鍵字的分布,適合關鍵字位數較多的情況。
5. 除留余數法
f(key) = key mod p (p≤m),m為散列表長。這種方法不僅可以對關鍵字直接取模,也可在折疊、平方取中后再取模。根據經驗,若散列表表長為m,通常p為小於或等於表長(最好接近m)的最小質數,可以更好的減小沖突。
此方法為最常用的構造散列函數方法。
6. 隨機數法
f(key) = random(key),這里random是隨機函數。當關鍵字的長度不等時,采用這個方法構造散列函數是比較合適的。
實際應用中,應該視不同的情況采用不同的散列函數。如果關鍵字是英文字符、中文字符、各種各樣的符號,都可以轉換為某種數字來處理,比如其unicode編碼。下面這些因素可以作為選取散列函數的參考:(1)計算散列地址所需的時間;(2)關鍵字長度;(3)散列表大小;(4)關鍵字的分布情況;(5)查找記錄的頻率。
【學習資料】: 《大話數據結構》