雜湊表查詢
一、雜湊表的基本概念
雜湊表(Hash Table)又稱散列表,是除順序表儲存結構、連結表儲存結構和索引表儲存結構之外的又一種儲存線性表的儲存結構。
雜湊表儲存的基本思路是:設要儲存的物件個數為n,設定一個長度為m(m≥n)的連續記憶體單元。
以線性表中每個物件的關鍵字ki(0≤i≤n-1)為自變數,通過一個稱為雜湊函式的函式h(ki),把ki對映為記憶體單元的地址(或稱下標)h(ki),並把該物件儲存在這個記憶體單元中。
h(ki)也稱為雜湊地址(又稱雜湊地址)。把如此構造的線性表儲存結構稱為雜湊表。
雜湊衝突:對於兩個關鍵字ki和kj(i≠j),有ki≠kj(i≠j),但h(ki)=h(kj)。
通常把這種具有不同關鍵字而具有相同雜湊地址的物件稱做“同義詞”
在雜湊表儲存結構的儲存中,同義詞衝突是很難避免的,除非關鍵字的變化區間小於等於雜湊地址的變化區間,而這種情況當關鍵字取值不連續時是非常浪費儲存空間的。通常的實際情況是關鍵字的取值區間遠大於雜湊地址的變化區間。
二、雜湊函式構造方法
構造雜湊函式的目標是使得到的雜湊地址儘可能均勻地分佈在n個連續記憶體單元地址上,同時使計算過程儘可能簡單以達到儘可能高的時間效率。
1. 直接定址法
直接定址法是以關鍵字k本身或關鍵字加上某個數值常量c作為雜湊地址的方法。
直接定址法的雜湊函式h(k)為:h(k)=k+c
這種雜湊函式計算簡單,並且不可能有衝突發生。
當關鍵字的分佈基本連續時
2. 除留餘數法
除留餘數法是用關鍵字k除以某個不大於雜湊表長度m的數p所得的餘數作為雜湊地址的方法。
除留餘數法的雜湊函式h(k)為:h(k)=k mod p (mod為求餘運算,p≤m)
p最好是質數(素數)。
3. 數字分析法
該方法是提取關鍵字中取值較均勻的數字位作為雜湊地址的方法。它適合於所有關鍵字值都已知的情況,並需要對關鍵字中每一位的取值分佈情況進行分析。
例如,對於一組關鍵字:{92317602,92326875,92739628,92343634,92706816,92774638,92381262,92394220}
通過分析可知,每個關鍵字從左到右的第1、2、3位和第6位取值較集中,不宜作為雜湊函式,剩餘的第4、5、7和8位取值較分散,可根據實際需要取其中的若干位作為雜湊地址。
若取最後兩位作為雜湊地址,則雜湊地址的集合為{2,75,28,34,16,38,62,20}。
三、雜湊衝突解決方法
在雜湊表中,雖然衝突很難避免,但發生衝突的可能性卻有大有小。這主要與三個因素有關:
1.與裝填因子有關
所謂裝填因子α是指雜湊表中已存入的元素數n與雜湊地址空間大小m的比值。
即α=n/m, α越小,衝突的可能性就越小; α越大(最大可取1),衝突的可能性就越大。
這很容易理解,因為α越小,雜湊表中空閒單元的比例就越大,所以待插入元素同已插入的元素髮生衝突的可能性就越小;
反之, α越大,雜湊表中空閒單元的比例就越小,所以待插入元素同已插入的元素衝突的可能性就越大;
另一方面, α越小,儲存空間的利用率就越低;反之,儲存空間的利用率也就越高。
為了既兼顧減少衝突的發生,又兼顧提高儲存空間的利用率這兩個方面,通常使最終的控制在0.6~0.9的範圍內。
2.與所採用的雜湊函式有關
若雜湊函式選擇得當,就可使雜湊地址儘可能均勻地分佈在雜湊地址空間上,從而減少衝突的發生;否則,若雜湊函式選擇不當,就可能使雜湊地址集中於某些區域,從而加大沖突的發生。
3.與解決衝突的雜湊衝突函式有關。
雜湊衝突函式選擇的好壞也將減少或增加發生衝突的可能性。
下面是解決方法:
1. 開放定址法
開放定址法是一類以發生衝突的雜湊地址為自變數,通過某種雜湊衝突函式得到一個新的空閒的雜湊地址的方法。
(1)線性探測法
線性探測法是從發生衝突的地址(設為d)開始,依次探測d的下一個地址(當到達下標為m-1的雜湊表表尾時,下一個探測的地址是表首地址0),直到找到一個空閒單元為止(當m≥n時一定能找到一個空閒單元)。
線性探測法的數學遞推描述公式為:
d0=h(k)
di=(di-1+1) mod m (1≤i≤m-1)
(2)平方探測法
設發生衝突的地址為d,則平方探測法的探測序列為:d±12,d±22,…。
平方探測法的數學描述公式為:
d0=h(k)
di=(d0± i2) mod m (1≤i≤m-1)
平方探測法是一種較好的處理衝突的方法,可以避免出現堆積問題。
它的缺點是不能探測到雜湊表上的所有單元,但至少能探測到一半單元。
例1,假設雜湊表長度m=13,採用除留餘數法雜湊函式建立如下關鍵字集合的雜湊表:
{16,74,60,43,54,90,46,31,29,88,77}。
解:n=11,m=13,
除留餘數法的雜湊函式為:h(k)=k mod p
p應為小於等於m的素數,假設p取值13。
則有:h(16)=3,h(74)=9,h(60)=8,h(43)=4,h(54)=2,h(90)=12,h(46)=7,h(31)=5,
h(29)=3 發生衝突
d0=h(29)=3,d1=(3+1) mod 13=4 仍有衝突
d2=(4+1) mod 13=5 仍有衝突
d3=(5+1) mod 13=6 解決衝突
h(88)=10
h(77)=12 發生衝突
d0=h(77)==12,d1=(12+1) mod 13=0 解決衝突
2. 拉鍊法
拉鍊法是把所有的同義詞用單鏈錶鏈接起來的方法。
在這種方法中,雜湊表每個單元中存放的不再是記錄本身,而是相應同義詞單鏈表的頭指標。
由於單鏈表中可插入任意多個節點,所以此時裝填因子α根據同義詞的多少既可以設定為大於1,也可以設定為小於或等於1,通常取α=1。
對上例構造的雜湊表採用拉鍊法解決衝突。
解:採用拉鍊法解決衝突建立的連結串列如下圖所示