天天看點

散清單(三):沖突處理的方法之開位址法(線性探測再散列的實作)

二、開位址法

基本思想:當關鍵碼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 産生哈希位址。