雜湊函式(雜湊函式,Hash Function)

2021-06-23 05:09:45 字數 3184 閱讀 5418

說明

雜湊的概念屬於查詢,它不以關鍵字的比較為基本操作,採用直接定址技術。在理想情況下,查詢的期望時間為o(1)。

簡單的說,hash函式就是把任意長的輸入字串變化成固定長的輸出字串的一種函式。輸出字串的長度稱為hash函式的位數。(下圖**於維基百科)

雜湊函式把訊息或資料壓縮成摘要,使得資料量變小,將資料的格式固定下來,比如我們自定義密碼的儲存。

一句話:雜湊(

hashing

)通過雜湊函式將要檢索的項與索引(雜湊,雜湊值)關聯起來,生成一種便於搜尋的資料結構(雜湊表)。 應用

雜湊函式的性質:

同一函式的雜湊值不相同,那麼其原始輸入也不相同,上圖中k1,k3和k4。(確定性)

雜湊函式的輸入和輸出不是唯一對應關係的,如果兩個雜湊值相同,兩個輸入值很可能是不相同的,上圖中的k2,k5這種情況稱為「雜湊碰撞」。(不確定性)

所以,安全避免衝突的條件,一是|u|的上限為m,(實際上很難滿足);二是選擇合適的hash函式。

q:衝突是不是可以避免的?

否。根據鴿巢原理可得,雜湊表的重複問題(衝突)是不可避免的,因為鍵的數目總是比索引的數目多,不管是多麼高明的演算法都不可能解決這個問題。就算鍵的數目比索引的數目少,必有乙個輸出串對應多個輸入串,衝突還是會發生。

hash函式的構造準則:簡單、均勻

1、  雜湊函式的計算簡單,快速;

2、  雜湊函式能將關鍵字集合k均勻地分布在位址集上,使衝突最小。

hash函式的構造方法:

1、直接定址法:

其中a和b為常數,這種雜湊函式叫做自身函式。

例:有乙個從1歲到100歲的人口數字統計表,其中,年齡作為關鍵字,雜湊函式取關鍵字自身。這樣,若要詢問25歲的人有多少,則只要查表的第25項即可。

由於直接定址所得位址集合和關鍵字集合的大小相同。因此,對於不同的關鍵字不會發生衝突。但實際中能使用這種雜湊函式的情況很少。

2、  相乘取整法

該方法包括兩個步驟:首先用關鍵字key乘上某個常數a(0該方法最大的優點是m的選取比除餘法要求更低。比如,完全可選擇它是2的整數次冪。雖然該方法對任何a的值都適用,但對某些值效果會更好。knuth建議選取

3、平方取中法

取關鍵字平方後的中間幾位為雜湊位址。

例:將一組關鍵字(0100,0110,1010,1001,0111)

平方後得(0010000,0012100,1020100,1002001,0012321)

4、摺疊法

將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進製)作為雜湊位址,這方法稱為摺疊法(folding)。

如國際標準圖書編號0-442-20586-4的雜湊位址分別如

5、除餘法:

這是一種最簡單,也最常用的構造雜湊函式的方法。它不僅可以對關鍵字直接取模(mod),也可在折迭、平方取中等運算之後取模。值得注意的是,在使用除留餘數法時,對p的選擇很重要。一般情況下可以選p為質數或不包含小於20的質因素的合數。

6、隨機數法

選擇乙個隨機函式,取關鍵字的隨機函式值為它的雜湊位址,即h(key)=random (key),其中random為隨機函式。通常,當關鍵字長度不等時採用此法構造雜湊函式較恰當。

處理衝突的方法:

1、開放定址法(不好理解啊)

基本思想:前者是將所有結點均存放在雜湊表[0..m-1]中。

當衝突發生時,使用某種探查(亦稱探測)技術在雜湊表中形成乙個探查(測)序列。沿此序列逐個單元地查詢,直到找到給定的關鍵字,或者碰到乙個開放的位址 (即該位址單元為空)為止(若要插入,在探查到開放的位址,則可將待插入的新結點存人該位址單元)。查詢時探查到開放的位址則表明表中無待查的關鍵字,即查詢失敗。

注意:用開放定址法建立雜湊表時,建表前須將表中所有單元(更嚴格地說,是指單元中儲存的關鍵字)置空。

怎麼用:

裝填因子:a,a一般取0.5到0.9之間。目的是為了確定合適的表長。

探查序列:

hi=(h(key)+di)mod m        i=1,2,…,k (k≤m-1) ,其中:h(key)為雜湊函式;m為雜湊表表長;di為增量序列,可有下列三種取法:

(1)    di=1,2,3,…,m-1,稱線性探測再雜湊;

(2)    di=12,-12,22,-22,33,…,±k2,(k≤m/2)稱二次探測再雜湊;

(3)    di=偽隨機數序列,稱偽隨機探測再雜湊。

例:利用探測法構造雜湊表:

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

這裡關鍵字個數n=10,不妨取m=13,此時α≈0.77,雜湊表為t[0..12],雜湊函式為:h(key)=key%13。

由除餘法的雜湊函式計算出的上述關鍵字序列的雜湊位址為

(0,10,2,12,5,2,3,12,6,12)。

步驟:1、前5個關鍵字插入時,其相應的位址均為開放位址,故將它們直接插入t[0],t[10),t[2],t[12]和t[5]中。

2、當插入第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]中。

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

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

參見動畫演示

2、鏈位址法

基本思想:將互為同義詞的結點鏈成乙個單鏈表,而將此鍊錶的頭指標放在雜湊表[0..m-1]中。

參考:維基百科

雜湊函式 雜湊函式 演算法

常用字串雜湊函式有bkdrhash,aphash,djbhash,jshash,rshash,sdbmhash,pjwhash,elfhash等等。c 實現 include define m 249997 define m1 1000003 define m2 10000019 大素數 using ...

什麼是雜湊演算法 雜湊函式 雜湊函式?

舉個例子,比如這裡有一萬首歌,給你一首新的歌x,要求你確認這首歌是否在那一萬首歌之內。無疑,將一萬首歌乙個乙個比對非常慢。但如果存在一種方式,能將一萬首歌的每首資料濃縮到乙個數字 稱為雜湊碼 中,於是得到一萬個數字,那麼用同樣的演算法計算新的歌x的編碼,看看歌x的編碼是否在之前那一萬個數字中,就能知...

雜湊 雜湊函式 衝突處理

例 如果我們現在要統計的是80後出生年份的人口數,那麼我們對出生年份這個關鍵字可以用年份減去1980來作為位址。此時f key key 1980。這樣的雜湊函式優點就是簡單 均勻,也不會產生衝突,但問題是這需要事先知道關鍵字的分布情況,適合查詢表較小且連續的情況。由於這樣的限制,在現實應用中,直接定...