1. 程式人生 > >常見的散列函數

常見的散列函數

原則 文件格式 對應關系 一個 原來 hash 不同 可能 目標

散列函數 在以下的討論中,我們假設處理的是值為整型的關鍵碼,否則我們總可以建立一種關鍵碼與正整數之間的一一對應關系,從而把該關鍵碼的檢索轉化為對與其對應的正整數的檢索;同時,進一步假定散列函數的值落在0到M-1之間。散列函數的選取原則是:運算盡可能簡單;函數的值域必須在散列表的範圍內;盡可能使得結點均勻分布,也就是盡量讓不同的關鍵碼具有不同的散列函數值。需要考慮各種因素:關鍵碼長度、散列表大小、關鍵碼分布情況、記錄的檢索頻率等等。下面我們介紹幾種常用的散列函數。 1、除余法 顧名思義,除余法就是用關鍵碼x除以M(往往取散列表長度),並取余數作為散列地址。除余法幾乎是最簡單的散列方法,散列函數為: h(x) = x mod M。 2、乘余取整法 使用此方法時,先讓關鍵碼key乘上一個常數A (0< A < 1),提取乘積的小數部分。然後,再用整數n乘以這個值,對結果向下取整,把它做為散列的地址。散列函數為: hash ( key ) = _LOW( n × ( A × key % 1 ) )。 其中,“A × key % 1”表示取 A × key 小數部分,即: A × key % 1 = A × key - _LOW(A × key), 而_LOW(X)是表示對X取下整。 3、平方取中法 由於整數相除的運行速度通常比相乘要慢,所以有意識地避免使用除余法運算可以提高散列算法的運行時間。平方取中法的具體實現是:先通過求關鍵碼的平方值,從而擴大相近數的差別,然後根據表長度取中間的幾位數(往往取二進制的比特位)作為散列函數值。因為一個乘積的中間幾位數與乘數的每一數位都相關,所以由此產生的散列地址較為均勻。 4、數字分析法 設有 n 個 d 位數,每一位可能有 r 種不同的符號。這 r 種不同的符號在各位上出現的頻率不一定相同,可能在某些位上分布均勻些,每種符號出現的幾率均等; 在某些位上分布不均勻,只有某幾種符號經常出現。可根據散列表的大小,選取其中各種符號分布均勻的若幹位作為散列地址。 5、基數轉換法 將關鍵碼值看成另一種進制的數再轉換成原來進制的數,然後選其中幾位作為散列地址。 6、折疊法 有時關鍵碼所含的位數很多,采用平方取中法計算太復雜,則可將關鍵碼分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(舍去進位)作為散列地址,這方法稱為折疊法。 7、ELFhash字符串散列函數 ELFhash函數在UNIX系統V 版本4中的“可執行鏈接格式”( Executable and Linking Format,即ELF )中會用到,ELF文件格式用於存儲可執行文件與目標文件。ELFhash函數是對字符串的散列。它對於長字符串和短字符串都很有效,字符串中每個字符都有同樣的作用,它巧妙地對字符的ASCII編碼值進行計算,ELFhash函數對於能夠比較均勻地把字符串分布在散列表中。

常見的散列函數