哈希值


總結性歸納:哈希值

 

 

 

哈希函數指將哈希表中元素的關鍵鍵值映射為元素存儲位置的函數。  
一般的線性表,樹中,記錄在結構中的相對位置是隨機的,即和記錄的關鍵字之間不存在確定的關系,因此,在結構中查找記錄時需進行一系列和關鍵字的比較。這一類查找方法建立在“比較“的基礎上,查找的效率依賴於查找過程中所進行的比較次數。 理想的情況是能直接找到需要的記錄,因此必須在記錄的存儲位置和它的關鍵字之間建立一個確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應。

 

 

什么是 Hash

 

Hash(哈希),又稱“散列”。

 

散列(hash)英文原意是“混雜”、“拼湊”、“重新表述”的意思。

 

在某種程度上,散列是與排序相反的一種操作,排序是將集合中的元素按照某種方式比如字典順序排列在一起,而散列通過計算哈希值,打破元素之間原有的關系,使集合中的元素按照散列函數的分類進行排列。

 

在介紹一些集合時,我們總強調需要重寫某個類的 equlas() 方法和 hashCode() 方法,確保唯一性。這里的 hashCode() 表示的是對當前對象的唯一標示。計算 hashCode 的過程就稱作 哈希。

為什么要有 Hash

 

我們通常使用數組或者鏈表來存儲元素,一旦存儲的內容數量特別多,需要占用很大的空間,而且在查找某個元素是否存在的過程中,數組和鏈表都需要挨個循環比較,而通過 哈希 計算,可以大大減少比較次數。

 

 

幾種常見的哈希函數(散列函數)構造方法

  • 直接定址法 
    • 取關鍵字或關鍵字的某個線性函數值為散列地址。
    • 即 H(key) = key 或 H(key) = a*key + b,其中a和b為常數。
  • 除留余數法 
    • 取關鍵字被某個不大於散列表長度 m 的數 p 求余,得到的作為散列地址。
    • 即 H(key) = key % p, p < m。 
  • 數字分析法 
    • 當關鍵字的位數大於地址的位數,對關鍵字的各位分布進行分析,選出分布均勻的任意幾位作為散列地址。
    • 僅適用於所有關鍵字都已知的情況下,根據實際應用確定要選取的部分,盡量避免發生沖突。
  • 平方取中法 
    • 先計算出關鍵字值的平方,然后取平方值中間幾位作為散列地址。
    • 隨機分布的關鍵字,得到的散列地址也是隨機分布的。
  • 折疊法(疊加法) 
    • 將關鍵字分為位數相同的幾部分,然后取這幾部分的疊加和(舍去進位)作為散列地址。
    • 用於關鍵字位數較多,並且關鍵字中每一位上數字分布大致均勻。 
  • 隨機數法 
    • 選擇一個隨機函數,把關鍵字的隨機函數值作為它的哈希值。
    • 通常當關鍵字的長度不等時用這種方法。 

構造哈希函數的方法很多,實際工作中要根據不同的情況選擇合適的方法,總的原則是盡可能少的產生沖突。

通常考慮的因素有關鍵字的長度和分布情況、哈希值的范圍等。

如:當關鍵字是整數類型時就可以用除留余數法;如果關鍵字是小數類型,選擇隨機數法會比較好。

哈希沖突的解決

選用哈希函數計算哈希值時,可能不同的 key 會得到相同的結果,一個地址怎么存放多個數據呢?這就是沖突。

常用的主要有兩種方法解決沖突:

1.鏈接法(拉鏈法)

拉鏈法解決沖突的做法是: 
將所有關鍵字為同義詞的結點鏈接在同一個單鏈表中。

若選定的散列表長度為 m,則可將散列表定義為一個由 m 個頭指針組成的指針數組 T[0..m-1] 。

凡是散列地址為 i 的結點,均插入到以 T[i] 為頭指針的單鏈表中。 
T 中各分量的初值均應為空指針。

在拉鏈法中,裝填因子 α 可以大於 1,但一般均取 α ≤ 1。

 

2.開放定址法

用開放定址法解決沖突的做法是:

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

簡單的說:當沖突發生時,使用某種探查(亦稱探測)技術在散列表中尋找下一個空的散列地址,只要散列表足夠大,空的散列地址總能找到。

按照形成探查序列的方法不同,可將開放定址法區分為線性探查法、二次探查法、雙重散列法等。

a.線性探查法

hi=(h(key)+i) % m ,0 ≤ i ≤ m-1 

基本思想是: 
探查時從地址 d 開始,首先探查 T[d],然后依次探查 T[d+1],…,直到 T[m-1],此后又循環到 T[0],T[1],…,直到探查到 有空余地址 或者到 T[d-1]為止。

b.二次探查法

hi=(h(key)+i*i) % m,0 ≤ i ≤ m-1 

基本思想是: 
探查時從地址 d 開始,首先探查 T[d],然后依次探查 T[d+1^2],T[d+2^2],T[d+3^2],…,等,直到探查到 有空余地址 或者到 T[d-1]為止。

缺點是無法探查到整個散列空間。

c.雙重散列法

hi=(h(key)+i*h1(key)) % m,0 ≤ i ≤ m-1 

基本思想是: 
探查時從地址 d 開始,首先探查 T[d],然后依次探查 T[d+h1(d)], T[d + 2*h1(d)],…,等。

該方法使用了兩個散列函數 h(key) 和 h1(key),故也稱為雙散列函數探查法。

定義 h1(key) 的方法較多,但無論采用什么方法定義,都必須使 h1(key) 的值和 m 互素,才能使發生沖突的同義詞地址均勻地分布在整個表中,否則可能造成同義詞地址的循環計算。

該方法是開放定址法中最好的方法之一。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM