選擇一個“好”的散列函數可以在在一定程度上減少沖突,但在實際應用中很難完全避免沖突,所以選擇一個有效的處理沖突的方法是非常重要的。創建散列表和查找散列表都會遇到沖突,這兩種情況下處理沖突的方法應該是一致的。
創建散列表的方法和散列表本身的組織形式有關。按照組織形式的不同通常分位兩大類:開放地址法和鏈地址法。
1.開放地址法
開放地址法的基本思想時:將記錄都存儲在散列表數組中,當某一記錄關鍵字經過散列函數的計算所得到的初始地址H0此時已有其他關鍵字占據(即發生沖突),采取合適的方法計算得到另一個地址,如果仍然發生沖突,就以此地址為基礎采取相同的計算方法,知道所得到的地址不再發生沖突。
這種方法在尋找下一個地址時,原來的數組空間對於所有的元素都是開放的,不管關鍵字key經過哈希函數計算所得到的初始地址是否與之相同,也沒有其他的要求任何的元素中可以存儲,所以稱作開放地址法。
可用公式表示為
其中H(key)表示哈希函數,m為散列表長度,di為增量序列。
根據di取值的不同可以分為以下兩種情況
(1)線性探測法
這種探測方法可以將散列表假象成一個循環表(實際並不是),發生沖突時,從沖突的下一單元順序尋找空單元,如果最后一個位置都沒有找到空單元,則回到表頭繼續查找,直到找到一個空位,就把此單元放入此空位。如果直到發生沖突的第一個單元(即經過哈希函數所得到的第一個初始地址)都沒空位,則說明散列表已滿,需要進行溢出處理
將一組關鍵字(9,1,23,14,55,20,84,27),采用散列函數:H(key)=key%7,表長為10,用線性探測法處理沖突
9%7=2 1%7=1 23%7=2(與9發生沖突)H=(H0+di)%(10-1) di=1 14%7=0
55%7=6 20%7=6(與55發生沖突)H=(H0+di)%(10-1) di=1
84%7=0(與14發生沖突) di=1,與1發生沖突 di=2,與9發生沖突 di=3,與23發生沖突 di=4,無沖突,所以di=4
27%7=6,與55,20發生沖突,所以di=2
(2)二次探測法
將一組關鍵字(9,1,23,14,55,20,84,27),采用散列函數:H(key)=key%7,表長為10,用二次探測法處理沖突
注意不是每次加di,而是從每加一次di都是從初始位置開始加的
2.鏈地址法
鏈地址法的基本思想是:將具有相同散列地址的記錄放在同一個單鏈表中,稱為同義詞鏈表,不需要處理沖突。
以前面相同的題為例,采用尾插法,下面是示意圖

以下是代碼演示
線性探測法的代碼實現
鏈式探測法的代碼實現





