散列表——數據結構

一,散列表的基本概念

直接將元素的儲存位置和其關鍵字之間建立某種直接關係,那麼在進行查找時,就無需做比較或做很少次的比較,按照這種關係直接由關鍵字找到相應的記錄,這就是散列表查找法的思想。

它通過對元素關鍵字值進行某種運算,直接求出元素的地址,即使用關鍵字到地址的直接轉換方法,而不需要反覆比較。因此散列查找法又稱爲雜湊法散列法

散列表中的術語:

  • 散列函數和散列地址:在記錄的存儲位置p和其關鍵字key之間建立一個確定的對應關係H,使得p=H(key),稱這個對應關係H爲散列函數,p爲散列地址
  • 散列表:一個有限連續的地址空間,用以存儲按散列函數計算得到相應散列地址的數據記錄。通常散列表的存儲空間是一個一維數組,散列地址是數組的下標。
  • 衝突和同義詞對不同的關鍵字可能得到同一散列地址,即key1 != key2,但是H(key1) == H(key2),這種現象稱爲衝突。具有相同函數值的關鍵字對該散列表函數來說稱爲同義詞,key1與key2互稱爲同義詞。
  • eg:A稱爲關鍵字key,則A經過關係H後,在數組中的位置稱爲存儲位置p;而不同的關鍵字8,4,經過關係(關鍵字%2)得到的存儲地址都是0,稱爲衝突,而8,4則爲同義詞
  • 二,散列函數的構造方法

要求:

  • 函數計算要簡單,每一關鍵字只能由一個散列地址與之對應
  • 函數的值域需在表長的範圍內,計算出的散列地址的分佈應均勻,儘可能減少衝突。

1,數字分析法

       適用情況:事先必須明確直到所有關鍵字每一位上各種數字的分佈情況,然後找到隨機的部分作爲散列地址

       eg:一串數組   123685311   123193511  123387411  123338911  123346511  123824711   123395411

               如這串數字可知,前三個數字和後兩個都一樣,所以這五位就不不能作爲散列地址,而中間四位近乎隨機,所以可以將中間四位任意搭配作爲散列地址。

2,平方取中法

        使用情況:不能事先了解關鍵字的所有情況,或難於直接從關鍵字中找到取值分散的幾位

        因爲在選定散列函數時不一定能知道關鍵字的全部情況,那麼取關鍵字中的哪幾位也不一定合適。所以將關鍵字平方後取中是一種比較常見的方法;

eg:關鍵字     內部編碼          內部編碼平方          取中做散列地址 

  • IDA1     09040101       081723426090201     426
  • IDB2     09040202       081725252200804     252
  • XID3     24090403       580347516702409     516
  • YID4     25090404       629528372883216     372

3,摺疊法

           使用情況:適合於散列地址的位數較少,而關鍵字的位數較多,且難於直接從關鍵字中1找到取值較分散的幾位

            eg:當散列表位數爲1000,而關鍵字key=45387765213,則可以將關鍵字按3位一段分割得到:453 877 652 13。採用移位疊加:453+877+652+13=995,H(key)=995;邊界疊加453+778+652+31=914,H(key)=914;即爲兩種方法的散列地址

(移位疊加是將分割後的每一部分的最低位對齊,然後相加;邊界疊加是將兩個相鄰的部分沿邊來回摺疊,然後對齊相加)

4,除留餘數法

這種方法計算簡單,適用範圍廣,是最常見的構造散列函數的方法。它不僅可以對關鍵字直接取模,也可在摺疊,平方取中等運算之後取模,這樣能夠保證散列地址一定落在散列表的地址空間中。

eg:假設散列表表長爲m,選擇一個不大於m的數p,用p去除關鍵字,除後所得餘數爲散列地址:H(key)=key%p。(這個方法的關鍵是選取適當的p,一般情況下,可以選取p爲小於表長的最大質數。例如,表長爲100,可以取p=97)

三,處理衝突的方法

1,開放尋址法

(1)開放尋址法

將散列表想成一個循環表,發生衝突時,從衝突的下一單元順序尋找空單元,如果最後一個位置也沒找到空單元,則回到表頭開始繼續查找,直到找到一個空位,就把此元素放入此空位中。如果找不到空位,則說明散列表已滿,需要進行溢出處理

按照加一,加二,加三的順序往後找(1,2,3,4,5,6,7,8........m-1)

(2)二次探測法

和線性探測法類似,但是按照另一種方法增加即(1*1,-1*1,2*2,-2*2,3*3,-3*3........k*k,-k*k(k<=m/2))

(3)僞隨機探測法

 設d=僞隨機序列,則散列地址=(H(key)+d)%m;

2,鏈地址法

把具有相同散列地址的記錄放在同一個單鏈表中,稱爲同義詞鏈表。

如果關鍵字AA,AAA,AAAA和A的散列地址相同,BB,BBB,BBBB和B的散列地址相同,則存儲如下

算法分析

1,雖然散列表在關鍵字與記錄的存儲位置之間建立了直接映像,但由於衝突的發生,使得散列表的查找過程依然是一個給定值和關鍵字進行比較的過程。因此仍需以平均查找長度作爲衡量散列表查找效率的量度。

2,查找過程中需和給定值進行比較的關鍵字個數取決於三個因素:散列函數,處理衝突的方法和填裝因子。

填裝因子a=表中填入的記錄數/散列表的長度

a越小,發生衝突的可能性就越小,a越大,表中已經填入的記錄越多,發生衝突的可能性就越大。

3,散列函數的「好壞」首先影響出現衝突的頻繁程度。但一般情況下認爲,凡是「均勻的」散列函數,對同一組隨機數的關鍵字,產生衝突的可能性相同,假設所設定的散列函數是「均勻的」,則影響平均查找長度的因素只有兩個——處理衝突的方法和填裝因子a。

 

查找成功時平均查找長度=1/m*(第一層個數*1+第二層個數*2+第三層個數*3+.....);

查找失敗時平均查找長度=1/m*(第一個同地址的數量+第二個相同地址的數量+......);