散列函數的概念

2019-09-11     linux內核

概念

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

hash函數就是把任意長的輸入字符串變化成固定長的輸出字符串的一種函數。輸出字符串的長度稱為hash函數的位數。

散列(Hashing)通過散列函數將要檢索的項與索引(散列,散列值)關聯起來,生成一種便於搜索的數據結構(散列表)。

應用

目前應用最為廣泛的hash函數是SHA-1和MD5,大多是128位和更長。hash函數在現實生活中應用十分廣泛。很多下載網站都提供下載文件的MD5碼校驗,可以用來判別文件是否完整,在一些BitTorrent下載中,軟體將通過計算MD5檢驗下載到的文件片段的完整性,etc。

性質

哈希衝突是不可避免的,因為鍵的數目總是比索引的數目多,不管是多麼高明的算法都不可能解決這個問題。就算鍵的數目比索引的數目少,必有一個輸出串對應多個輸入串,衝突還是會發生。

哈希函數構造準則

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

(1)散列函數的計算簡單,快速;

(2)散列函數能將關鍵字集合K均勻地分布在地址集{0,1,…,m-1}上,使衝突最小。

  1. 哈希函數的構造方法

(1)直接定址法:

取關鍵字或關鍵字的某個線性函數值為哈希地址:H(key) = key 或 H(key) = a·key + b 其中a和b為常數,這種哈希函數叫做自身函數。

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

(2)相乘取整法:

首先用關鍵字key乘上某個常數A(0 < A < 1),並抽取出key.A的小數部分;然後用m乘以該小數後取整。

注意:該方法最大的優點是m的選取比除余法要求更低。比如,完全可選擇它是2的整數次冪。雖然該方法對任何A的值都適用,但對某些值效果會更好。Knuth建議選取 0.61803……。

(3)平方取中法:

取關鍵字平方後的中間幾位為哈希地址。

通過平方擴大差別,另外中間幾位與乘數的每一位相關,由此產生的散列地址較為均勻。這是一種較常用的構造哈希函數的方法。

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

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

若取表長為1000,則可取中間的三位數作為散列地址集:(100,121,201,020,123)。

(4)除留餘數法:

取關鍵字被數p除後所得餘數為哈希地址:H(key) = key MOD p (p ≤ m)。

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

(5)隨機數法:

選擇一個隨機函數,取關鍵字的隨機函數值為它的哈希地址,即 H(key) = random (key),其中random為隨機函數。通常,當關鍵字長度不等時採用此法構造哈希函數較恰當。

文章來源: https://twgreatdaily.com/_K-3Nm0BJleJMoPMiqOk.html