雜湊表基本概念介紹及雜湊衝突的處理方法 附原始碼

2021-10-07 20:13:19 字數 4244 閱讀 3607

處理衝突的方法

**實現

雜湊表(雜湊表),是根據關鍵碼值(key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊(雜湊)函式,存放記錄的陣列叫做雜湊(雜湊)表。

給定表m,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址,則稱表m為雜湊(hash)表,函式f(key)為雜湊(hash) 函式。

資料的雜湊位址=f(關鍵字的值)

雜湊位址只是表示在查詢表中的儲存位置,而不是實際的物理儲存位置。f()是乙個函式,通過這個函式可以快速求出該關鍵字對應的的資料的雜湊位址,稱之為「雜湊函式」。

取關鍵字或關鍵字的某個線性函式值為雜湊位址。即h(key)=keyh(key) = a·key + b,其中a和b為常數(這種雜湊函式叫做自身函式)。若其中h(key)中已經有值了,就往下乙個找,直到h(key)中沒有值了,就放進去。

例如有乙個從 1 歲到 100 歲的人口數字統計表

假設其雜湊函式為第一種形式,其關鍵字的值表示最終的儲存位置。若需要查詢年齡為 25 歲的人口數量,將年齡 25 帶入雜湊函式中,直接求得其對應的雜湊位址為 25(求得的雜湊位址表示該記錄的位置在查詢表的第 25 位)。一般用陣列實現。

如果關鍵字由多位字元或者數字組成,就可以考慮抽取其中的 2 位或者多位作為該關鍵字對應的雜湊位址,在取法上盡量選擇變化較多的位,避免衝突發生。

比如一組員工的出生年月日,這時我們發現出生年月日的前幾位數字大體相同,這樣的話,出現衝突的機率就會很大,但是我們發現年月日的後幾位表示月份和具體日期的數字差別很大,如果用後面的數字來構成雜湊位址,則衝突的機率會明顯降低。因此數字分析法就是找出數字的規律,盡可能利用這些資料來構造衝突機率較低的雜湊位址。

對關鍵字做平方操作,取中間得幾位作為雜湊位址。此方法也是比較常用的構造雜湊函式的方法。

例如關鍵字序列為,對各個關鍵字進行平方後的結果為,則可以取中間的兩位作為其雜湊位址。

例如,在圖書館中圖書都是以乙個 10 位的十進位制數字為關鍵字進行編號的,若對其查詢表建立雜湊表時,就可以使用摺疊法。

若某書的編號為:0-442-20586-4,分割方式如圖 1 中所示,在對其進行摺疊時有兩種方式:一種是移位摺疊,另一種是間界摺疊:

取關鍵字被某個不大於雜湊表表長m的數p除后所得的餘數為雜湊位址。即 h(key) = key mod p,p<=m。不僅可以對關鍵字直接取模,也可在摺疊、平方取中等運算之後取模。

對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞(即衝突)。

由經驗得知 p 可以為不大於 m 的質數或者不包含小於 20 的質因數的合數

注意:這裡的隨機函式其實是偽隨機函式,隨機函式是即使每次給定的 key 相同,但是 h(key)都是不同;而偽隨機函式正好相反,每個 key 都對應的是固定的 h(key)

如此多的構建雜湊函式的方法,在選擇的時候,需要根據實際的查詢表的情況採取適當的方法。通常考慮的因素有以下幾方面:

雜湊衝突只能儘量減少但是不能完全避免了,通常處理雜湊衝突的方法有以下幾種

h(key)=(h(key)+ d)mod m(其中 m 為雜湊表的表長,d 為乙個增量)

當得出的雜湊位址產生衝突時,選取以下 3 種方法中的一種獲取 d 的值,然後繼續計算,直到計算出的雜湊位址不在衝突為止,這 3 種方法為:

當通過雜湊函式求得的雜湊位址同其他關鍵字產生衝突時,使用另乙個雜湊函式計算,直到衝突不再發生。

將所有產生衝突的關鍵字所對應的資料全部儲存在同乙個線性鍊錶中。例如有一組關鍵字為,其雜湊函式為:h(key)=key mod 13,使用鏈位址法所構建的雜湊表如下圖 所示:

建立兩張表,一張為基本表,另一張為溢位表。基本表儲存沒有發生衝突的資料,當關鍵字由雜湊函式生成的雜湊位址產生衝突時,就將資料填入溢位表。

在雜湊表中進行查詢的操作同雜湊表的構建過程類似,其具體實現思路為:對於給定的關鍵字k,將其帶入雜湊函式中,求得與該關鍵字對應的資料的雜湊位址,如果該位址中沒有資料,則證明該查詢表中沒有儲存該資料,查詢失敗:如果雜湊位址中有資料,就需要做進一步的證明(排除衝突的影響),找到該資料對應的關鍵字同k 進行比對,如果相等,則查詢成功;反之,如果不相等,說明在構造雜湊表時發生了衝突,需要根據構造表時設定的處理衝突的方法找到下乙個位址,同位址中的資料進行比對,直至遇到位址中資料為null(說明查詢失敗),或者比對成功

/*

* @author: carlos

* @date: 2020-07-2 23:48:50

* @lastedittime: 2020-07-2 23:48:50

* @lasteditors: carlos

* @description: hash

*/#include

"stdio.h"

#include

"stdlib.h"

#define hashsize 7

//定義雜湊表長為陣列的長度

#define nullkey -1

typedef

struct

hashtable;

/** * @description: 雜湊函式初始化

* @param: hashtable *hashtable 結構體指標

* @return: 無

* @author: carlos

*/void

init

(hashtable *hashtable)

}/**

* @description: 雜湊函式(除留餘數法)

* @param: int data 雜湊的資料

* @return: 雜湊後data儲存的位址

* @author: carlos

*/int

hash

(int data)

/** * @description: 雜湊表的插入函式,可用於構造雜湊表

* @param: hashtable *hashtable 結構體指標,int data 雜湊的資料

* @return: 無

* @author: carlos

*/void

insert

(hashtable *hashtable,

int data)

hashtable->elem[hashaddress]

= data;

}/**

* @description: 雜湊表的查詢演算法

* @param: hashtable *hashtable 結構體指標,int data 雜湊的資料

* @return: 無

* @author: carlos

*/int

search

(hashtable *hashtable,

int data)

}return hashaddress;

}int

main()

;//初始化雜湊表

init

(&hashtable)

;//利用插入函式構造雜湊表

for(i =

0; i < hashsize; i++

)//呼叫查詢演算法

result =

search

(&hashtable,29)

;if(result ==-1

)printf

("查詢失敗");

else

printf

("29 在雜湊表中的位置是:%d"

, result +1)

;return0;

}

雜湊表基本概念介紹及雜湊衝突的處理方法 附原始碼

目錄處理衝突的方法 實現 雜湊表 雜湊表 是根據關鍵碼值 key value 而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊 雜湊 函式,存放記錄的陣列叫做雜湊 雜湊 表。給定表m,存在函式f key 對任意給定的關鍵字值ke...

雜湊函式和雜湊衝突的基本概念

雜湊法又稱雜湊法 雜湊法以及關鍵字位址計算法等,相應的表成為雜湊表。基本思想 首先在元素的關鍵字k和元素的位置p之間建立乙個對應關係f,使得p f k 其中f成為雜湊函式。建立雜湊表時,把關鍵字k的元素直接存入位址為f k 的單元 查詢關鍵字k的元素時利用雜湊函式計算出該元素的儲存位置p f k 建...

雜湊表 基本概念

雜湊表,又稱為雜湊表,是一種根據鍵來直接訪問記憶體位置的一種資料結構。它通過乙個計算鍵值的函式 雜湊函式 來將所查詢的資料對映到雜湊表中的乙個位置來查詢該位置的內容,從而達到快速查詢的目的。存放記錄的陣列就稱為雜湊表 若關鍵字為k,則其值就存放在f k 對應的位置上,這樣可以實現不用比較就可以直接找...