二、開位址法
基本思想:當關鍵碼key的哈希位址H0 = hash(key)出現沖突時,以H0為基礎,産生另一個哈希位址H1 ,如果H1仍然沖突,再以H0
為基礎,産生另一個哈希位址H2 ,…,直到找出一個不沖突的哈希位址Hi ,将相應元素存入其中。這種方法有一個通用的再散列函
數形式:

其中H0 為hash(key) ,m為表長,di稱為增量序列。增量序列的取值方式不同,相應的再散列方式也不同。主要有以下四種:
線性探測再散列
二次探測再散列
僞随機探測再散列
雙散列法
(一)、線性探測再散列
假設給出一組表項,它們的關鍵碼為 Burke, Ekers, Broad, Blum, Attlee, Alton, Hecht, Ederly。采用的散列函數是:取其第一個字母在
字母表中的位置。
hash (x) = ord (x) - ord (‘A’)
這樣,可得
hash (Burke) = 1hash (Ekers) = 4
hash (Broad) = 1hash (Blum) = 1
hash (Attlee) = 0hash (Hecht) = 7
hash (Alton) = 0hash (Ederly) = 4
又設散清單為HT[26],m = 26。采用線性探查法處理溢出,則上述關鍵碼在散清單中散列位置如圖所示。紅色括号内的數字表示找
到空桶時的探測次數。比如輪到放置Blum 的時候,探測位置1,被占據,接着向下探測位置2還是不行,最後放置在位置3,總的探
測次數是3。
堆積現象
散列位址不同的結點争奪同一個後繼散列位址的現象稱為堆積(Clustering),比如ALton 本來位置是0,直到探測了6次才找到合适位
置5。這将造成不是同義詞的結點也處在同一個探測序列中,進而增加了探測序列長度,即增加了查找時間。若散列函數不好、或裝
填因子a 過大,都會使堆積現象加劇。
下面給出具體的實作代碼,大體跟前面講過的鍊位址法差異不大,隻是利用的結構不同,如下:
status 儲存狀态,有EMPTY, DELETED, ACTIVE,删除的時候隻是邏輯删除,即将狀态置為DELETED,當插入新的key 時,隻要不
是ACTIVE 的位置都是可以放入,如果是DELETED位置,需要将原來元素先釋放free掉,再插入。
common.h:
hash.h:
hash.c:
main.c:
simba@ubuntu:~/Documents/code/struct_algorithm/search/hash_table/linear_probing$ ./main
The hash table has allocate.
4568 BBBB 23
not found
The hash table has free.
與鍊位址法 示例還有一點不同,就是key 使用的是int 類型,是以必須再實作一個hash_int 哈希函數,根據key 産生哈希位址。