那發生了雜湊衝突,我們該如何處理呢?
有兩種方法: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.當插入的資料佔總大小的一定比率的時候,也稱負載因子,我們可以對雜湊表進行擴容,重新通過雜湊函式求得位置...