教你從零開始寫乙個雜湊表 雜湊函式

2021-09-03 01:35:06 字數 1251 閱讀 4625

在這一節,我們來編寫雜湊函式。

我們選擇的雜湊函式應該具有(以下特性):

我們使用的是常見的字串雜湊函式,偽**的表達如下:

function hash(string, a, num_buckets):

hash = 0

string_len = length(string)

for i = 0, 1, ..., string_len:

hash += (a ** (string_len - (i+1))) * char_code(string[i])

hash = hash % num_buckets

return hash

這個雜湊函式有兩個步驟:

一起來試一下這個雜湊函式吧:

hash("cat", 151, 53)

hash = (151**2 * 99 + 151**1 * 97 + 151**0 * 116) % 53

hash = (2257299 + 14647 + 116) % 53

hash = (2272062) % 53

hash = 5

調整變數a的值,將會得到不同的雜湊函式。

hash(「cat」, 163, 53) = 3

// hash_table.c

static

intht_hash

(const

char

* s,

const

int a,

const

int m)

return

(int

)hash;

}

理想的雜湊函式往往會產生均勻的分布。然而,所有的雜湊函式都存在病態的輸入集。這些輸入都將雜湊到同乙個值中。為了找出這一類輸入,我們用輸入值域中的乙個大集合的輸入來執行這個函式。病態的資料集會雜湊到乙個特定的桶中。

病態輸入集的存在意味著世間沒有對所有輸入都完美的的雜湊函式。我們能做的是對於預期輸入集設計乙個表現良好的雜湊函式。

病態輸入也導致了乙個安全問題。如果乙個使用者惡意地向雜湊表寫入一堆衝突的關鍵字,那麼搜尋這些關鍵字會花費超過(o(n))複雜度的時間,而不是(o(1))。這可能會被不懷好意的人用來針對那些使用了雜湊表的系統,進行拒絕服務攻擊,例如dns和某些web服務。

教你從零開始寫乙個雜湊表–雜湊表結構

教你從零開始寫乙個雜湊表–雜湊衝突

教你從零開始寫乙個雜湊表 雜湊衝突

雜湊函式把乙個無窮大的輸入集合對映到乙個有限大小的輸出集合。不同的關鍵字可能會被對映到同乙個陣列下標,如此一來就導致了雜湊衝突。雜湊表必須實現解決衝突的方法。我們的雜湊表將使用開放位址法和再雜湊法。在桶索引衝突後,再雜湊法會使用兩個雜湊函式來計算鍵值對將要儲存的桶索引值。有關其他雜湊衝突的解決方法,...

教你從零開始寫乙個雜湊表 導讀

雜湊表是乙個可以提供快速實現關聯陣列api的資料結構。跟 雜湊表 有關的一些術語也許有些讓人產生困惑,因此我在下文列了一些摘要。雜湊表由一系列的桶組成,每乙個桶儲存乙個鍵值對。為了找到存放鍵值對的桶,關鍵字要傳遞給雜湊函式。雜湊函式返回乙個指明桶陣列下標的整數。當我們想要查詢乙個鍵值對時,我們對雜湊...

C語言寫乙個雜湊表

目錄 雜湊表,就是下標可以為字母的陣列。假設現有乙個陣列int a 100 想查詢其中第40個元素,則直接輸入a 40 就可以了,時間複雜度為o 1 o 1 o 1 問題在於,當下標不是數字,而是乙個字串的時候,可能需要乙個超大的空間才能將所有下標妥善地存放在特定的位置。例如,若以大小寫字母作為下標...