搜索結構之哈希----初識哈希

搜索結構之哈希

1>順序搜索以及二叉樹搜索樹中,元素存儲位置和元素各關鍵碼之間沒有對應的關係,因此在查找一個元素時,必須要經過關鍵碼的多次比較。搜索的效率取決於搜索過程中元素的比較次數。
2>理想的搜索方法:可以不經過任何比較,一次直接從表中得到要搜索的元素。
如果構造一種存儲結構,通過某種函數(hashFunc)使元素的存儲位置與它的關鍵碼之間能夠建立一一映射的關係,那麼在查找時通過該函數可以很快找到該元素。
3>當向該結構中:
插入元素時:根據待插入元素的關鍵碼,以此函數計算出該元素的存儲位置並按此位置進行存放
搜索元素時:對元素的關鍵碼進行同樣的計算,把求得的函數值當做元素的存儲位置,在結構中按此位置取元素比較,若關鍵碼相等,則搜索成功

該方式即爲哈希(散列)方法,哈希方法中使用的轉換函數稱爲哈希(散列)函數,構造出來的結構稱爲哈希表(Hash Table)(或者稱散列表)

例如:數據集合{180,750,600,430,541,900,460}


用該方法進行搜索不必進行多次關鍵碼的比較,因此搜索的速度比較快

問題:按照上述哈希方式,向集合中插入元素443,會出現什麼問題?

哈希衝突

對於兩個數據元素的關鍵字:HashFun(Ki) == HashFun(Kj)

即不同關鍵字通過相同哈希哈數計算出相同的哈希地址,該種現象稱爲哈希衝突或哈希碰撞。把具有不同關鍵碼而具有相同哈希地址的數據元素稱爲“同義詞”。

發生哈希衝突該如何處理呢?

哈希函數:

引起哈希衝突的一個原因可能是:哈希函數設計不夠合理。
哈希函數設計原則:
哈希函數的定義域必須包括需要存儲的全部關鍵碼,而如果散列表允許有m個地址時,其值域必須在0到m-1之間
哈希函數計算出來的地址能均勻分佈在整個空間中
哈希函數應該比較簡單
【常見哈希函數】
直接定製法
取關鍵字的某個線性函數爲散列地址:Hash(Key)= A*Key + B
優點:簡單、均勻
缺點:需要事先知道關鍵字的分佈情況
適合查找比較小且連續的情況

除留餘數法
設散列表中允許的地址數爲m,取一個不大於m,但最接近或者等於m的質數p作爲除數,按照哈希函數:Hash(key) = key
% p(p<=m),將關鍵碼轉換成哈希地址

平方取中法

假設關鍵字爲1234,對它平方就是1522756,抽取中間的3位227作爲哈希地址;
再比如關鍵字爲4321,對它平方就是18671041,抽取中間的3位671(或710)作爲哈希地址
平方取中法比較適合:不知道關鍵字的分佈,而位數又不是很大的情況
摺疊法
摺疊法是將關鍵字從左到右分割成位數相等的幾部分(最後一部分位數可以短些),然後將這幾部分疊加求和,並按散列表表
長,取後幾位作爲散列地址
摺疊法適合事先不需要知道關鍵字的分佈,適合關鍵字位數比較多的情況
隨機數法
選擇一個隨機函數,取關鍵字的隨機函數值爲它的哈希地址,即H(key) = random(key),其中random爲隨機數函數
通常應用於關鍵字長度不等時採用此法
數學分析法
設有n個d位數,每一位可能有r種不同的符號,這r種不同的符號在各位上出現的頻率不一定相同,可能在某些位上分佈比較均
勻,每種符號出現的機會均等,在某些位上分佈不均勻只有某幾種符號經常出現。可根據散列表的大小,選擇其中各種符號分
布均勻的若干位作爲散列地址。例如:
假設要存儲某家公司員工登記表,如果用手機號作爲關鍵字,那麼極有可能前7位都是 相同的,那麼我們可以選擇後面的四位
作爲散列地址,如果這樣的抽取工作還容易出現 衝突,還可以對抽取出來的數字進行反轉(如1234改成4321)、右環位移(如
1234改成4123)、左環移位、前兩數與後兩數疊加(如1234改成12+34=46)等方法
數字分析法通常適合處理關鍵字位數比較大的情況,如果事先知道關鍵字的分佈且關鍵字的若干位分佈較均勻的情況
注意:哈希函數設計的越精妙,產生哈希衝突的可能性就越低,但是無法避免哈希衝突.

處理哈希衝突---閉散列和開散列吐舌頭吐舌頭吐舌頭請看下一篇哦




發佈了47 篇原創文章 · 獲贊 32 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章