教你從零開始寫一個哈希表--哈希衝突

  哈希函數把一個無窮大的輸入集合映射到一個有限大小的輸出集合。不同的關鍵字可能會被映射到同一個數組下標,如此一來就導致了哈希衝突。哈希表必須實現解決衝突的方法。
  我們的哈希表將使用開放地址法和再散列法。在桶索引衝突後,再散列法會使用兩個哈希函數來計算鍵值對將要保存的桶索引值。
  有關其他哈希衝突的解決方法,請查看附錄

再散列法

  索引i衝突後應該使用的新的索引位置根據下面的函數給出:
  index = hash_a(string) + i * hash_b(string) % num_buckets
  我們看到,如果沒有哈希衝突的發生,i=0。此時,桶索引是字符串的hash_a值。如果發生了衝突,索引將由hash_b進行調整。
  有種可能是,hash_b返回了0,導致i*hash_b(string)%num_buckets也返回了0。這會使得哈希表不停的向同一個桶中插入鍵值對。我們可以通過對第二個哈希的結果加一來避免這種情況,以確保第二個項的結果不會是0。
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;
}

上一篇:教你從零開始寫一個哈希表–哈希函數
下一篇:教你從零開始寫一個哈希表–接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章