上一章咱們解釋了Hash table
中最重要的hash函數
,並用僞代碼和C語言實現了一個咱們本身的hash函數
,hash函數
中碰撞
是沒法避免的,當發生碰撞
時咱們改如何有效的處理呢?這章咱們就來說解下。算法
hash函數
中將無限大的輸入映射到有限的輸出中,當不一樣的輸入映射到相同的輸出時,就會發生碰撞
,每一個的hash表
都會採用不一樣的方法來處理碰撞
。函數
咱們的哈希表將使用一種稱爲開放地址的雙重哈希的技術來處理衝突。雙重哈希使用兩個散列函數來計算在發生碰撞
後存儲記錄的索引。.net
當i
發生碰撞
後咱們使用以下方式來獲取索引:3d
index = hash_a(string) + i * hash_b(string) % num_buckets
當沒有發生碰撞
時,i=0
,因此索引就是hash_a
的值,發生碰撞
後,hash_a
的結果就須要通過一次hash_b
的處理。code
hash_b
可能會返回0
,將第二項減小到0
,這就致使hash表
會將多個記錄插入到同一個bucket
中,咱們能夠在hash_b
的結果後加1
來處理這種狀況,確保它永遠不會爲0
:blog
index = (hash_a(string) + i * (hash_b(string) + 1)) % num_buckets
// hash_table.c static int ht_get_hash(const char* s, const int num_buckets, const int attempt) { const int hash_a = ht_hash(s, HT_PRIME_1, num_buckets); const int hash_b = ht_hash(s, HT_PRIME_2, num_buckets); return (hash_a + (attempt * (hash_b + 1))) % num_buckets; }
上一章:hash函數 下一章:完成Hash表API索引