3 雜湊函式設計 直接定址法

2021-06-17 18:00:08 字數 1122 閱讀 4501

雜湊函式的設計原則

1. 計算簡單

你說設計乙個演算法可以保證所有的關鍵字都不會產生衝突,但是這個演算法需要很複雜的計算,會耗費很多時間,這對於需要頻繁地查詢來說,就會大大降低查詢的效率了。因此雜湊函式的計算時間不應該超過其他查詢技術與關鍵字比較的時間。

2. 雜湊位址分布均勻

我們前面也提到衝突帶來的問題,最好的辦法就是盡量讓雜湊位址均勻地分布在儲存空間中,這樣可以保證儲存空間的有效利用,並減少為處理衝突而耗費的時間。

簡單科普一下,以php為例。php的hash採用的是目前最為普遍的djbx33a (daniel j. bernstein, times 33 with addition),這個演算法被廣泛運用與多個軟體專案,apache、perl和berkeley db等。對於字串而言這是目前所知道的最好的雜湊演算法,原因在於該演算法的速度非常快,而且分類非常好(衝突小,分布均勻)。

下面我們逐個介紹一些常用的雜湊函式構造方法。估計設計這些方法的前輩們當年可能是從事間諜工作,因為這些方法都是將原來數字按某種規律變成另乙個數字而已。首先是直接定址法。

直接定址法

如果我們現在要對0-100歲的人口數字統計表,那麼我們對年齡這個關鍵字就可以直接用年齡的數字作為位址。此時f(key) = key。

如果我們現在要統計的是80後出生年份的人口數,那麼我們對出生年份這個關鍵字可以用年份減去1980來作為位址。此時f (key) = key-1980。

假如今年是2023年,那麼2023年出生的人就是20歲了,此時 f(2000) = 2000 - 1980,可以找得到位址20,位址20裡儲存了資料「人數500萬」。

也就是說,我們可以取關鍵字的某個線性函式值為雜湊位址,即:

f(key) = a × key + b

這樣的雜湊函式優點就是簡單、均勻,也不會產生衝突,但問題是這需要事先知道關鍵字的分布情況,適合查詢表較小且連續的情況。由於這樣的限制,在現實應用中,直接定址法雖然簡單,但卻並不常用。

雜湊 開放定址法

引起雜湊衝突的乙個原因可能是 雜湊函式設計不夠合理。雜湊函式設計原則 雜湊函式的定義域必須包括需要儲存的全部關鍵碼,而如果雜湊表允許有m個位址時,其值域必須在0到m 1之間 雜湊函式計算出來的位址能均勻分布在整個空間中 雜湊函式應該比較簡單 閉雜湊typedef int keytype typede...

雜湊(閉雜湊)開放定址法實現

之前一篇博文中提過如何用開鏈法實現雜湊表 這裡是鏈結 那麼對於雜湊表的實現,還有另外一種方法的實現,這就是雜湊開放定址法來實現。該方法也是用來處理雜湊衝突的。解決思想如下 現有關鍵字17,60,29,38 如何確定位址?可以看見該錶的長度為11,那麼使用關鍵字取餘該錶的長度,得到的餘數就是該關鍵字的...

直接定址法的應用(hash雜湊的定義及整數雜湊)

給出n個正整數,再給出m個正整數,問這m個數中的每個數分別是否在n個數 現過,其中n,m 10 5,且所有正整數均不超過10 5。例如n 5,m 3,n個正整數為,欲查詢的m個正整數為 7,4,2 於是後者中只有7和2在n個正整數 現過,而4是沒有出現過的。第一行輸入兩個數字,分別表示n,m,第二行...