1. 程式人生 > >簡單通俗地理解Hash雜湊儲存

簡單通俗地理解Hash雜湊儲存

先來了解一下Hash的基本思路:

設要儲存物件的個數為num, 那麼我們就用len個記憶體單元來儲存它們(len>=num); 以每個物件ki的關鍵字為自變數,用一個函式h(ki)來映射出ki的記憶體地址,也就是ki的下標,將ki物件的元素內容全部存入這個地址中就行了。這個就是Hash的基本思路。
Hash為什麼這麼想呢?換言之,為什麼要用一個函式來映射出它們的地址單元呢?
This is a good question.明白了這個問題,Hash不再是問題。下面我就通俗易懂地向你來解答一下這個問題。
現在我要儲存4個元素 13 7 14 11

顯然,我們可以用陣列來存。也就是:a[1] = 13; a[2] = 7; a[3] = 14; a[4] = 11;

當然,我們也可以用Hash來存。下面給出一個簡單的Hash儲存:

先來確定那個函式。我們就用h(ki) = ki%5;(這個函式不用糾結,我們現在的目的是瞭解為什麼要有這麼一個函式)。

對於第一個元素 h(13) = 13%5 = 3; 也就是說13的下標為3;即Hash[3] = 13;

對於第二個元素 h(7) = 7 % 5 = 2; 也就是說7的下標為2; 即Hash[2] = 7;

同理,Hash[4] = 14; Hash[1] = 11;

好了,存現在是存好了。但是,這並沒有體現出Hash的妙處,也沒有回答剛才的問題。下面就來揭開它神祕的面紗吧。

現在我要你查詢11這個元素是否存在。你會怎麼做呢?當然,對於陣列來說,那是相當的簡單,一個for迴圈就可以了。

也就是說我們要找4次。

下面我們來用Hash找一下。

首先,我們將要找的元素11代入剛才的函式中來映射出它所在的地址單元。也就是h(11) = 11%5 = 1 了。下面我們來比較一下Hash[1]?=11, 這個問題就很簡單了。也就是說我們就找了1次。這個就是Hash的妙處了。至此,剛才的問題也就得到了解答。至此,你也就徹底的明白了Hash了。

Hash衝突的處理

已知一組關鍵字為(26,36,41,38,44,15,68,12,06,51),用除餘法構造雜湊函式,用線性探查法解決衝突構造這組關鍵字的散列表。

解答:

為了減少衝突,通常令裝填因子α     

由除餘法的雜湊函式計算出的上述關鍵字序列的雜湊地址為(0,10,2,12,5,2,3,12,6,12)。

前5個關鍵字插入時,其相應的地址均為開放地址,故將它們直接插入T[0],T[10),T[2],T[12]和T[5]中。

當插入第6個關鍵字15時,其雜湊地址2(即h(15)=15%13=2)已被關鍵字41(15和41互為同義詞)佔用。

故探查h1=(2+1)%13=3,此地址開放,所以將15放入T[3]中。

當插入第7個關鍵字68時,其雜湊地址3已被非同義詞15先佔用,故將其插入到T[4]中。

當插入第8個關鍵字12時,雜湊地址12已被同義詞38佔用,故探查hl=(12+1)%13=0,而T[0]亦被26佔用,再探查h2=(12+2)%13=1,此地址開放,可將12插入其中。

類似地,第9個關鍵字06直接插入T[6]中;而最後一個關鍵字51插人時,因探查的地址12,0,1,…,6均非空,故51插入T[7]中。

假定一個待雜湊儲存的線性表為(32,75,29,63,48,94,25,46,18,70),雜湊地址空間為HT[13]

若採用除留餘數法構造雜湊函式和線性探測法處理衝突

試求出每一元素的初始雜湊地址和最終雜湊地址,畫出最後得到的散列表,求出平均查詢長度


呃呃呃,這個圖是直接網上的,有時間用電腦畫一下,,