1. 程式人生 > >哈希表和沖突解決

哈希表和沖突解決

ges table 偽隨機 沖突解決 tro 技術分享 位數 位置 元素

1.散列表

  散列表(Hash table,也叫哈希表),是根據鍵(Key)而直接訪問在內存存儲位置的數據結構。也就是說,它通過計算一個關於鍵值的函數,將所需查詢的數據映射到表中一個位置來訪問記錄,這加快了查找速度。這個映射函數稱做散列函數,存放記錄的數組稱做散列表。

2.散列函數

散列函數能使對一個數據序列的訪問過程更加迅速有效,通過散列函數,數據元素將被更快定位。

(1). 直接定址法:取關鍵字或關鍵字的某個線性函數值為散列地址。即{ hash(k)=k} 或{ hash(k)=a*k+b} ,其中a,b為常數(這種散列函數叫做自身函數)

(2). 數字分析法:假設關鍵字是以r為基的數,並且哈希表中可能出現的關鍵字都是事先知道的,則可取關鍵字的若幹數位組成哈希地址。

(3). 平方取中法:取關鍵字平方後的中間幾位為哈希地址。通常在選定哈希函數時不一定能知道關鍵字的全部情況,取其中的哪幾位也不一定合適,而一個數平方後的中間幾位數和數的每一位都相關,由此使隨機分布的關鍵字得到的哈希地址也是隨機的。取的位數由表長決定。

(4). 折疊法:將關鍵字分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(舍去進位)作為哈希地址。

(5). 隨機數法

(6). 除留余數法:取關鍵字被某個不大於散列表表長m的數p除後所得的余數為散列地址。不僅可以對關鍵字直接取模,也可在折疊法、平方取中法等運算之後取模。對p的選擇很重要,一般取素數或m,若p選擇不好,容易產生沖突。

3.沖突解決

為了知道沖突產生的相同散列函數地址所對應的關鍵字,必須選用另外的散列函數,或者對沖突結果進行處理。而不發生沖突的可能性是非常之小的,所以通常對沖突進行處理。常用方法有以下幾種:

(1).開放定址法

技術分享

增量序列可有下列取法:{ di=1,2,3...(m-1)}或者為其他線性函數稱為線性探測。相當於逐個探測存放地址的表,直到查找到一個空單元,把散列地址存放在該空單元。當稱為平方探測、二次探測。偽隨機數序列,稱為偽隨機探測。

(2).單獨鏈表法(鏈地址法)

將散列到同一個存儲位置的所有元素保存在一個鏈表中。實現時,一種策略是散列表同一位置的所有沖突結果都是用棧存放的,新元素被插入到表的前端還是後端完全取決於怎樣方便。

(3).雙散列、再散列

根據不同的散列函數,即在同義詞產生地址沖突時計算另一個散列函數地址,直到沖突不再發生,這種方法不易產生“聚集”,但增加了計算時間。

(4).建立一個公共的溢出區

4.查詢效率

散列表的查找過程基本上和造表過程相同。一些關鍵碼可通過散列函數轉換的地址直接找到,另一些關鍵碼在散列函數得到的地址上產生了沖突,需要按處理沖突的方法進行查找。在介紹的三種處理沖突的方法中,產生沖突後的查找仍然是給定值與關鍵碼進行比較的過程。所以,對散列表查找效率的量度,依然用平均查找長度來衡量。查找過程中,關鍵碼的比較次數,取決於產生沖突的多少,產生的沖突少,查找效率就高,產生的沖突多,查找效率就低。因此,影響產生沖突多少的因素,也就是影響查找效率的因素。影響產生沖突多少有以下三個因素:

1. 散列函數是否均勻;

2. 處理沖突的方法;

3. 散列表的裝填因子。

散列表的裝填因子定義為:α= 填入表中的元素個數 / 散列表的長度

α是散列表裝滿程度的標誌因子。由於表長是定值,α與“填入表中的元素個數”成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。

哈希表和沖突解決