資料結構 閉雜湊處理雜湊衝突(線性探測)

2021-08-20 08:45:36 字數 2654 閱讀 8307

那發生了雜湊衝突,我們該如何處理呢?

有兩種方法:1.閉雜湊,如線性探測;2.開雜湊,例如:雜湊桶

這裡我們用閉雜湊的方式來解決雜湊衝突。

那如何去找下乙個空餘的位置呢?

線性探測法,拿我們上次的關鍵碼集合為例,雜湊表的大小為10,假設雜湊函式為hash(key) = key % 10:

當再往表裡插入43時,發現了它和753發生了碰撞,那我們就必須要找出下乙個存放43的位置。

線性探測的處理方法是:從發生衝突開始,依次繼續向後探測,直到找到空位置為止。

所以,我們從下標為3的位置開始往後找,發現它的下乙個位置即下標為4為空,那麼就將43插入到此位置。

a = 填入表中的元素個數 / 雜湊表的長度

a是雜湊表裝滿程度的標誌因子。由於表長是定值,a與表中元素個數成正比。所以,a越大,表中元素越多,發生衝突的可能性就越大。

因此,因嚴格限制a在0.7-0.8以下,超過0.8,查表時的cpu快取不命中按指數曲線上公升。

接下來,我們來對雜湊表進行插入、查詢和刪除操作。

乙個雜湊表裡應包含乙個成員陣列和雜湊函式,而陣列的每個元素又是鍵值對型別,所以它的每乙個元素可以定義為乙個結構體,對雜湊表的定義如下:

#define hashmaxsize 1000

typedef size_t keytype;

typedef size_t valtype;

typedef

enum

stat;

typedef size_t (*hashfunc)(keytype key);

//這個結構體代表雜湊表中的乙個元素

//這個元素中同時也包含了鍵值對

typedef

struct hashelem

hashelem;

typedef

struct hashtable

hashtable;

插入

1.使用雜湊函式找到待插入元素在雜湊表中的位置

2.如果該位置沒有元素(即狀態不是有效的)則直接插入新元素;如果該位置有元素且和待插入元素相等,則不用插入;如果該位置有元素但是和待插入元素不相等,發生雜湊衝突,線性探測找到下乙個空位置,將元素插入。

**如下:

void hashinsert(hashtable* ht,keytype key,valtype value)

//1.判定hash表是否能繼續插入(根據負載因子來判斷)

//這裡我們把負載因子定為0.8

if(ht->size >=0.8 * hashmaxsize)

//2.如果能繼續插入,根據key來計算offset

size_t offset = ht->func(key);

//3.從offet位置開始向後線性探測,找到第乙個狀態為empty的元素進行插入

while(1)

else

if(ht->data[offset].key == key && ht->data[offset].stat == valid)

else}}

return;

}

查詢

1.根據雜湊函式找到要查詢元素在雜湊表中的位置

2.如果該位置狀態為空,說明不存在;如果該位置狀態為有效且和待查詢元素值一樣,說明找到了;如果該位置狀態有效但和待查詢元素值不一致,繼續線性的向後探測,當把雜湊表遍歷完後還是沒找到,說明該元素不存在。

**:

int hashfind(hashtable* ht,keytype key,valtype* value)

//1.根據key計算出offse

size_t offset = ht->func(key);

//2.從offset開始向後查詢,每找到乙個元素,比較其key值和要查詢的key是否相同

while(1)

else

if(ht->data[offset].stat == empty)

else}}

}

刪除

1.根據雜湊函式找到要刪除元素在雜湊表中的位置

2.如果該位置有效且和待刪除元素值一樣,直接刪除;如果該位置狀態為空,說明不存在,刪除失敗;如果該位置有效但和要刪除元素值不一致,繼續線性的向後探測。

**:

void hashremove(hashtable* ht,keytype key)

if(ht->size == 0)

//1.根據key確定offset

size_t offset = ht->func(key);

//2.從offset開始,判斷當前元素的key是否和要刪除元素的key值相同

while(1)

// b)如果當前元素狀態為空,說明沒找到,直接返回

else

if(ht->data[offset].stat == empty)

else

}}//迴圈結束

return;

}

雜湊衝突 閉雜湊與開雜湊

閉雜湊 也叫開放定址法,當發生雜湊衝突時,如果雜湊表未被裝滿,說明在雜湊表中必然還有空位置,那麼可以把key存放到衝突位置中的 下乙個 空位置中去。include using namespace std 雜湊表每個空間給個標記 empty此位置空,exist此位置已經有元素,delete元素已經刪除...

資料結構 處理雜湊衝突的方法

摘自大話資料結構 我們設計得再好的雜湊函式也不可能完全避免衝突,這就像我們再健康也只能盡量預防疾病,但卻無法保證永遠不得病一樣,既然衝突不能避免,就要考慮如何處理它。那麼當我們在使用雜湊函式後發現兩個關鍵字key1 key2,但是卻有f key1 f key2 即有衝突時,怎麼辦呢?我們可以從生活中...

資料結構 Hashtable 閉雜湊

雜湊表是常見資料結構中一種擁有高效插入,高效查詢的結構,時間複雜度為o 1 閉雜湊雜湊的不足之處就是隨著衝突的資料增多,插入的效率也會隨之變慢,為了優化閉雜湊雜湊的效率,我們可以採取以下的方式 1.當插入的資料佔總大小的一定比率的時候,也稱負載因子,我們可以對雜湊表進行擴容,重新通過雜湊函式求得位置...