解決雜湊衝突的三種方法

2022-03-06 08:04:45 字數 1491 閱讀 2365

上篇博文我們舉的例子,hashmap,hashset其實都是採用的拉鍊法來解決雜湊衝突的,就是在每個位桶實現的時候,我們採用鍊錶(jdk1.8之後採用鍊錶+紅黑樹)的資料結構來去訪問發生雜湊衝突的輸入域的關鍵字(也就是被雜湊函式對映到同乙個位桶上的關鍵字)。首先來看使用拉鍊法解決雜湊衝突的幾個操作:

①插入操作:在發生雜湊衝突的時候,我們輸入域的關鍵字去對映到位桶(實際上是實現位桶的這個資料結構,鍊錶或者紅黑樹)中去的時候,我們先檢查帶插入元素x是否出現在表中,很明顯,這個查詢所用的次數不會超過裝載因子(n/m:n為輸入域的關鍵字個數,m為位桶的數目),它是個常數,所以插入操作的最壞時間複雜度為o(1)的。

②查詢操作:和①一樣,在發生雜湊衝突的時候,我們去檢索的時間複雜度不會超過裝載因子,也就是檢索資料的時間複雜度也是o(1)的

③刪除操作:如果在拉鍊法中我們想要使用鍊錶這種資料結構來實現位桶,那麼這個鍊錶一定是雙向鍊錶,因為在刪除乙個元素x的時候,需要更改x的前驅元素的next指標的屬性,把x從鍊錶中刪除。這個操作的時間複雜度也是o(1)的。

與開放定址法相比,拉鍊法有如下幾個優點:

①拉鍊法處理衝突簡單,且無堆積現象,即非同義詞決不會發生衝突,因此平均查詢長度較短;

②由於拉鍊法中各煉表上的結點空間是動態申請的,故它更適合於造表前無法確定表長的情況;

③開放定址法為減少衝突,要求裝填因子α較小,故當結點規模較大時會浪費很多空間。而拉鍊法中可取α≥1,且結點較大時,拉鍊法中增加的指標域可忽略不計,因此節省空間;

④在用拉鍊法構造的雜湊表中,刪除結點的操作易於實現。只要簡單地刪去鍊錶上相應的結點即可。

拉鍊法的缺點

指標需要額外的空間,故當結點規模較小時,開放定址法較為節省空間,而若將節省的指標空間用來擴大雜湊表的規模,可使裝填因子變小,這又減少了開放定址法中的衝突,從而提高平均查詢速度。

使用例子:hashmap

開放位址法有個非常關鍵的特徵,就是所有輸入的元素全部存放在雜湊表裡,也就是說,位桶的實現是不需要任何的鍊錶來實現的,換句話說,也就是這個雜湊表的裝載因子不會超過1。它的實現是在插入乙個元素的時候,先通過雜湊函式進行判斷,若是發生雜湊衝突,就以當前位址為基準,根據再定址的方法(探查序列),去尋找下乙個位址,若發生衝突再去尋找,直至找到乙個為空的位址為止。所以這種方法又稱為再雜湊法。

有幾種常用的探查序列的方法:

①線性探查

(使用例子:threadlocal裡面的threadlocalmap)

②二次探查

di=12,-12,22,-22,…,k2,-k2    ( k<=m/2 );這種方法的特點是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。

③ 偽隨機探測

di=偽隨機數序列;具體實現時,應建立乙個偽隨機數發生器,(如i=(i+p) % m),生成乙個位隨機序列,並給定乙個隨機數做起點,每次去加上這個偽隨機數++就可以了。

再雜湊法其實很簡單,就是再使用雜湊函式去雜湊乙個輸入的時候,輸出是同乙個位置就再次雜湊,直至不發生衝突位置

缺點:每次衝突都要重新雜湊,計算時間增加。

解決雜湊衝突的三種方式

開放位址法有個非常關鍵的特徵,就是所有輸入的元素全部存放在雜湊表裡,也就是說,位桶的實現是不需要任何的鍊錶來實現的,換句話說,也就是這個雜湊表的裝載因子不會超過1。它的實現是在插入乙個元素的時候,先通過雜湊函式進行判斷,若是發生雜湊衝突,就以當前位址為基準,根據再定址的方法 探查序列 去尋找下乙個位...

解決雜湊衝突的幾種方法

雖然我們不希望發生衝突,但實際上發生衝突的可能性仍是存在的。當關鍵字值域遠大於雜湊表的長度,而且事先並不知道關鍵字的具體取值時。衝突就難免會發 生。另外,當關鍵字的實際取值大於雜湊表的長度時,而且表中已裝滿了記錄,如果插入乙個新記錄,不僅發生衝突,而且還會發生溢位。因此,處理衝突和溢位是 雜湊技術中...

解決雜湊衝突的幾種方法

雜湊演算法 的目的就是將一串很大的資料根據一定的規則轉換為較小的資料。把任意長度的二進位制值串對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始資料對映之後得到的二進位制值串就是雜湊值。在這個轉換過程中,總會出現兩個不同的資料在經過雜湊演算法的計算後生成了相同的雜湊值。這就是雜湊...