雖然我們不希望發生衝突,但實際上發生衝突的可能性仍是存在的。當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時。衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄,如果插入乙個新記錄,不僅發生衝突,而且還會發生溢位。因此,處理衝突和溢位是 雜湊技術中的兩個重要問題。
用開放定址法解決衝突的做法是:當衝突發生時,使用某種探查(亦稱探測)技術在雜湊表中形成乙個探查(測)序列。沿此序列逐個單元地查詢,直到找到給定 的關鍵字,或者碰到乙個開放的位址(即該位址單元為空)為止(若要插入,在探查到開放的位址,則可將待插入的新結點存人該位址單元)。查詢時探查到開放的 位址則表明表中無待查的關鍵字,即查詢失敗。
開放定址法;hi=(h(key) + di) mod m,i=1,2,…,k(k<=m-1),其中h(key)為雜湊函式,m為雜湊表長,di為增量序列
使用開放定址發,非同義詞也可能產生衝突
注意:①用開放定址法建立雜湊表時,建表前須將表中所有單元(更嚴格地說,是指單元中儲存的關鍵字)置空。
②空單元的表示與具體的應用相關。
按照形成探查序列的方法不同,可將開放定址法區分為線性探查法、線性補償探測法、隨機探測等。
di=1,2,3,…,m-1,稱線性探測再雜湊;
該方法的基本思想是:
d,d+l,d+2,…,m-1,0,1,…,d-1
即:探查時從位址d開始,首先探查t[d],然後依次探查t[d+1],…,直到t[m-1],此後又迴圈到t[0],t[1],…,直到探查到t[d-1]為止。
探查過程終止於三種情況:
(1)若當前探查的單元為空,則表示查詢失敗(若是插入則將key寫入其中);
(2)若當前探查的單元中含有key,則查詢成功,但對於插入意味著失敗;
(3)若探查到t[d-1]時仍未發現空單元也未找到key,則無論是查詢還是插入均意味著失敗(此時表滿)。
用線性探測法處理衝突,思路清晰,演算法簡單,但存在下列缺點:
① 處理溢位需另程式設計序。一般可另外設立乙個溢位表,專門用來存放上述雜湊表中放不下的記錄。此溢位表最簡單的結構是順序表,查詢方法可用順序查詢。
② 按上述演算法建立起來的雜湊表,刪除工作非常困難。假如要從雜湊表 ht 中刪除乙個記錄,按理應將這個記錄所在位置置為空,但我們不能這樣做,而
只能標上已被刪除的標記,否則,將會影響以後的查詢。
③ 線性探測法很容易產生堆聚現象。所謂堆聚現象,就是存入雜湊表的記錄在表中連成一片。按照線性探測法處理衝突,如果生成雜湊位址的連續序列愈長 ( 即不同關鍵字值的雜湊位址相鄰在一起愈長 ) ,則當新的記錄加入該錶時,與這個序列發生衝突的可能性愈大。因此,雜湊位址的較長連續序列比較短連續序列生長得快,這就意味著,一旦出現堆聚 ( 伴隨著衝突 ) ,就將引起進一步的堆聚。
di=1^2,(-1)^2,2^2,(-2)^2,(3)^2,…,±(k)^2,(k<=m/2)稱二次探測再雜湊;
線性補償探測法的基本思想是:
將線性探測的步長從 1 改為 q ,即將上述演算法中的 j = (j + 1) % m 改為: j = (j + q) % m ,而且要求 q 與 m 是互質的,以便能探測到雜湊表中的所有單元。
【例】 pdp-11 小型計算機中的匯程式設計序所用的符合表,就採用此方法來解決衝突,所用表長 m = 1321 ,選用 q = 25 。
di=偽隨機數序列,稱偽隨機探測再雜湊。
每個key下次的步長是一樣的,不同的key之間的步長是隨機的
隨機探測的基本思想是:
(1)拉鍊法解決衝突的方法
拉鍊法解決衝突的做法是:將所有關鍵字為同義詞的結點鏈結在同乙個單鏈表中。若選定的雜湊表長度為m,則可將雜湊表定義為乙個由m個頭指標組成的指標數 組t[0..m-1]。凡是雜湊位址為i的結點,均插入到以t[i]為頭指標的單鏈表中。t中各分量的初值均應為空指標。在拉鍊法中,裝填因子α可以大於 1,但一般均取α≤1。
(2)拉鍊法的優點
與開放定址法相比,拉鍊法有如下幾個優點:
①拉鍊法處理衝突簡單,且
無堆積現象,即
非同義詞決不會發生衝突,因此平均查詢長度較短;
②由於拉鍊法中各煉表上的結點空間是動態申請的,故它更
適合於造表前無法確定表長的情況;
③開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指標域可忽略不計,因此節省空間;
④在用拉鍊法構造的雜湊表中,
刪除結點的操作易於實現。只要簡單地刪去鍊錶上相應的結點即可。而對開放位址法構造的雜湊表,刪除結點不能簡單地將被刪結 點的空間置為空,否則將截斷在它之後填人雜湊表的同義詞結點的查詢路徑。這是因為各種開放位址法中,空位址單元(即開放位址)都是查詢失敗的條件。因此在 用開放位址法處理衝突的雜湊表上執行刪除操作,只能在被刪結點上做刪除標記,而不能真正刪除結點。
(3)拉鍊法的缺點
拉鍊法的缺點是:
指標需要額外的空間,故當結點規模較小時,開放定址法較為節省空間,而若將節省的指標空間用來擴大雜湊表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均查詢速度。
hi=rhi(key),i=1,2,…,k rhi均是不同的雜湊函式,即在同義詞產生位址衝突時計算另乙個雜湊函式位址,直到衝突不再發生,這種方法不易產生「聚集」,但增加了計算時間。
這也是處理衝突的一種方法。假設雜湊函式的值域為[0,m-1],則設向量hashtable[0 ·· m-1]為基本表,每個分量存放乙個記錄,另設立向量overtable[0 ·· v]為溢位表。所有關鍵字和基本表中關鍵字為同義詞的記錄,不管它們由雜湊函式得到的雜湊位址是什麼,一旦發生衝突,都能填入溢位表。
解決雜湊衝突的幾種方法
雜湊演算法 的目的就是將一串很大的資料根據一定的規則轉換為較小的資料。把任意長度的二進位制值串對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始資料對映之後得到的二進位制值串就是雜湊值。在這個轉換過程中,總會出現兩個不同的資料在經過雜湊演算法的計算後生成了相同的雜湊值。這就是雜湊...
解決Hash衝突的幾種方法
雖然我們不希望發生衝突,但實際上發生衝突的可能性仍是存在的。當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時 衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄,如果插入乙個新記錄,不僅發生衝突,而且還會發生溢位 因此,處理衝突和溢位是 雜湊技術中...
解決雜湊衝突的三種方法
上篇博文我們舉的例子,hashmap,hashset其實都是採用的拉鍊法來解決雜湊衝突的,就是在每個位桶實現的時候,我們採用鍊錶 jdk1.8之後採用鍊錶 紅黑樹 的資料結構來去訪問發生雜湊衝突的輸入域的關鍵字 也就是被雜湊函式對映到同乙個位桶上的關鍵字 首先來看使用拉鍊法解決雜湊衝突的幾個操作 插...