雜湊函式:乙個把查詢表中的關鍵字對映成該關鍵字對應的位址的函式,記為hash(key)=addr。
雜湊函式可能會把兩個或者兩個以上的關鍵字對映到同乙個位址,稱這種情況為」衝突「,這裡發生碰撞的不同關鍵字稱為」同義詞「。一方面,設計好的雜湊函式應該儘量減少這樣的衝突;另一方面,由於這樣的衝突總是不可避免的,所以還要設計好的處理衝突的方法。
雜湊表:是根據關鍵字而直接進行訪問的資料結構。也就是說,雜湊表建立了關鍵字和儲存位址之間的一種直接對映關係。
理想情況下,對雜湊表進行查詢的時間複雜度為o(1),即與表中元素的個數無關,下面將分別介紹常用的雜湊函式和處理衝突的方法。
在構造雜湊函式時,必須注意以下幾點:
1)雜湊函式的定義域必須包含全部需要儲存的關鍵字,而值域的範圍依賴於雜湊表的大小或位址範圍。
2)雜湊函式計算出來的位址應該能等概率,均勻地分布在整個位址空間,從而減少衝突的發生。
3)三類函式應盡可能簡單,能夠在較短的時間內計算出任意關鍵字對應的雜湊位址。
下面介紹常用的雜湊函式:
1.直接定址法
直接取關鍵字的某個線性函式值為雜湊位址,雜湊函式為
h(key)=a×key+b;式中,a和b是常數。這種方法計算最簡單,並且不會產生衝突。它適合關鍵字的分布基本連續的情況,若關鍵字不連續,空位比較多,將造成儲存空間的浪費。
2.除留餘數法
h(key)=key%p除留餘數法的關鍵是選好p,使得每乙個關鍵字通過該函式轉換後等概率地對映到雜湊空間上的任一位址,從而盡可能減少衝突的可能性。
3.數字分析法
設關鍵字是r進製數,而r個數碼在各個位上出現的頻率不一定相同,可能在某些位上分布地均勻些,每種數碼出現的機會均等;而在某些位上分布不均勻,只有某幾種數碼經常數顯,則應該選取數碼分布較為均勻的若干位作為雜湊位址。這種方法適用於已知的關鍵字集合,如果更換了關鍵字就需要重新構造新的雜湊函式。
平方取中法
顧名思義,取關鍵字的平方值的中間幾位作為雜湊位址。具體取多少位要看實際情況而定。這種方法得到的雜湊位址與關鍵字的每一位都有關係,使得雜湊位址分布比較均勻。適用於關鍵字的每一位取值都不夠均勻或小於雜湊位址所需的位數。
摺疊法
將關鍵字分割成位數相同的幾個部分,然後取這幾部分的疊加和作為雜湊位址,這種方法成為摺疊法。關鍵字位數很多,而且關鍵字中每一位上數字分布大致均勻時,可以採用摺疊法得到雜湊位址。
在不同情況下,不同的雜湊函式會發揮出不同的效能,因此不能籠統地說哪種雜湊函式最好。在實際的選擇中,採用何種構造雜湊函式的方法取決於關鍵字的集合的情況,但是目標是為了使得產生衝突的可能性盡量地降低。
應該注意大哦,任何涉及出來的雜湊函式都不可能絕對地避免衝突,為此,必須考慮在發生衝突時應該如何進行處理,即為產生衝突的關鍵字尋找下乙個空的hash位址。
假設已經選定雜湊函式h(key),下面用hi表示發生衝突後第i次探測的雜湊位址。
hi=(h(key)+di)%m式中,i=1,2...k(k<m-1),m表示雜湊表表長,di為增量序列。
當去頂某乙個增量序列之後,則對應的處理方法是可以確定的。通常有以下四種取法:
1.線性探測法
當d1=1,2….m-1時,成為線性探測發。這種方法的特點是:衝突發生時,順序檢視表中下乙個單元,知道找出乙個空閒單元或者查遍全表。
線性探測發可能使第i個雜湊位址的同義詞存入第i+1個雜湊位址,這樣本應該存入第i+1個雜湊位址的元素就爭奪第i+2個雜湊位址的元素的位址……從而造成大量元素在相鄰的雜湊位址上聚集起來,大大降低了查詢效率。
2.平方探測法
當di=1²,2²,3²….,k²,其中k≤m/2,其中m必須是乙個可以表示成4k+3的質數,又成為二次探測法。
平方探測法是一種比較好的處理衝突的方法,可以避免出現堆積問題,它的缺點是不能探測到雜湊表是所有單元,但至少能探測到一半單元。
3.再雜湊法
當di=hash2(key),又成為雙雜湊法。需要使用兩個雜湊函式,當通過第乙個雜湊函式h(key)得到的雜湊位址發生衝突時,則利用第二個雜湊函式hash2(key),計算該關鍵字的位址增量。再雜湊法中,最多經過m-1次探測就會遍歷表中所有位置,回到h0的位置。
4.偽隨機序列法
當di=偽隨機序列時,成為偽隨機序列法。
注意:在開放定址的情況下,不能物理刪除表中已有的元素,因為若刪除元素則會將截斷其他具有相同雜湊位址的元素的查詢位址(因為後面的位址元素在查詢到空位址時候會認為表中不存在這個元素)。所以若想刪除乙個元素時,給它做乙個刪除標記,進行邏輯刪除。但這樣做的***是:在執行多次刪除之後,表面上看起來雜湊表很滿,實際上有許多位置沒有利用,因此需要定期維護雜湊表,要把刪除標記的元素物理刪除
5.拉鍊法
顯然,對於不同的關鍵字可能會通過雜湊函式對映到同乙個位址,為了避免非同義詞發生衝突,可以把所有的同義詞儲存在乙個線性鍊錶中,這個線性鍊錶由其雜湊位址唯一標識。假設雜湊位址為i的同義詞鍊錶的頭指標存放在雜湊表的第i個單元中,因而查詢、插入和刪除操作主要在同義詞鏈中進行。拉鍊法用於經常進行插入和刪除的情況。
例如,關鍵字序列為{19,14,23,01,68,20,84,27,55,11,10,79},雜湊函式h(key)=key%13,用拉鍊法處理衝突,建立的表為:
雜湊表的查詢效率取決於三個因素:雜湊函式,處理衝突的方法和裝填因子。
裝填因子:雜湊表的裝填因子一般記為a,定義為乙個表的裝滿程度,即:
a=表中記錄n/雜湊表長度m雜湊表的平均查詢長度依賴於雜湊表的填裝因子a,而不直接依賴於n或m。直觀的看,a越大,表示裝填的記錄越滿,發生衝突的可能性就越大,反之發生衝突的可能性越小。
資料結構 Hashtable 閉雜湊
雜湊表是常見資料結構中一種擁有高效插入,高效查詢的結構,時間複雜度為o 1 閉雜湊雜湊的不足之處就是隨著衝突的資料增多,插入的效率也會隨之變慢,為了優化閉雜湊雜湊的效率,我們可以採取以下的方式 1.當插入的資料佔總大小的一定比率的時候,也稱負載因子,我們可以對雜湊表進行擴容,重新通過雜湊函式求得位置...
資料結構 雜湊表(Hash Table)
雜湊表是一種根據關鍵碼去尋找值的資料對映結構,該結構通過把關鍵碼對映的位置去尋找存放值的地方。本質是乙個陣列,陣列中每乙個元素稱為乙個箱子 bin 箱子中存放的是鍵值對。雜湊表的儲存過程如下 根據 key 計算出它的雜湊值 h。假設箱子的個數為 n,那麼這個鍵值對應該放在第 f n 個箱子中。f x...
資料結構 雜湊表(Hash Table)
前言 在實際應用中,很多時候我們map儲存的元素是不需要講究順序,key也不需要具備可比較性的。接下來我們就來了解一下雜湊表 hash table 1.基本概念 這些資料由 key 和 value 組成,雜湊表底層是陣列,key 通過雜湊函式計算 o 1 級別的計算 後,得到陣列的索引,然後在陣列索...