在這一節,我們來編寫雜湊函式。
我們選擇的雜湊函式應該具有(以下特性):
我們使用的是常見的字串雜湊函式,偽**的表達如下:
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 問題在於,當下標不是數字,而是乙個字串的時候,可能需要乙個超大的空間才能將所有下標妥善地存放在特定的位置。例如,若以大小寫字母作為下標...