直接將元素的儲存位置和其關鍵字之間建立某種直接關係,那麼在進行查找時,就無需做比較或做很少次的比較,按照這種關係直接由關鍵字找到相應的記錄,這就是散列表查找法的思想。
它通過對元素關鍵字值進行某種運算,直接求出元素的地址,即使用關鍵字到地址的直接轉換方法,而不需要反覆比較。因此散列查找法又稱爲雜湊法或散列法
散列表中的術語:
適用情況:事先必須明確直到所有關鍵字每一位上各種數字的分佈情況,然後找到隨機的部分作爲散列地址
eg:一串數組 123685311 123193511 123387411 123338911 123346511 123824711 123395411
如這串數字可知,前三個數字和後兩個都一樣,所以這五位就不不能作爲散列地址,而中間四位近乎隨機,所以可以將中間四位任意搭配作爲散列地址。
使用情況:不能事先了解關鍵字的所有情況,或難於直接從關鍵字中找到取值分散的幾位
因爲在選定散列函數時不一定能知道關鍵字的全部情況,那麼取關鍵字中的哪幾位也不一定合適。所以將關鍵字平方後取中是一種比較常見的方法;
eg:關鍵字 內部編碼 內部編碼平方 取中做散列地址
- IDA1 09040101 081723426090201 426
- IDB2 09040202 081725252200804 252
- XID3 24090403 580347516702409 516
- YID4 25090404 629528372883216 372
使用情況:適合於散列地址的位數較少,而關鍵字的位數較多,且難於直接從關鍵字中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;即爲兩種方法的散列地址
(移位疊加是將分割後的每一部分的最低位對齊,然後相加;邊界疊加是將兩個相鄰的部分沿邊來回摺疊,然後對齊相加)
這種方法計算簡單,適用範圍廣,是最常見的構造散列函數的方法。它不僅可以對關鍵字直接取模,也可在摺疊,平方取中等運算之後取模,這樣能夠保證散列地址一定落在散列表的地址空間中。
eg:假設散列表表長爲m,選擇一個不大於m的數p,用p去除關鍵字,除後所得餘數爲散列地址:H(key)=key%p。(這個方法的關鍵是選取適當的p,一般情況下,可以選取p爲小於表長的最大質數。例如,表長爲100,可以取p=97)
(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;
把具有相同散列地址的記錄放在同一個單鏈表中,稱爲同義詞鏈表。
如果關鍵字AA,AAA,AAAA和A的散列地址相同,BB,BBB,BBBB和B的散列地址相同,則存儲如下
1,雖然散列表在關鍵字與記錄的存儲位置之間建立了直接映像,但由於衝突的發生,使得散列表的查找過程依然是一個給定值和關鍵字進行比較的過程。因此仍需以平均查找長度作爲衡量散列表查找效率的量度。
2,查找過程中需和給定值進行比較的關鍵字個數取決於三個因素:散列函數,處理衝突的方法和填裝因子。
填裝因子a=表中填入的記錄數/散列表的長度
a越小,發生衝突的可能性就越小,a越大,表中已經填入的記錄越多,發生衝突的可能性就越大。
3,散列函數的「好壞」首先影響出現衝突的頻繁程度。但一般情況下認爲,凡是「均勻的」散列函數,對同一組隨機數的關鍵字,產生衝突的可能性相同,假設所設定的散列函數是「均勻的」,則影響平均查找長度的因素只有兩個——處理衝突的方法和填裝因子a。
查找成功時平均查找長度=1/m*(第一層個數*1+第二層個數*2+第三層個數*3+.....);
查找失敗時平均查找長度=1/m*(第一個同地址的數量+第二個相同地址的數量+......);