動態hash演算法實現

2021-07-13 09:28:21 字數 2474 閱讀 1647

傳統hash表的實現主要有拉鍊法和開放位址雜湊法,而開放位址雜湊法又包括線性雜湊、二次雜湊等。當插入hash表的元素不斷增加時,傳統hash表為保證查詢效率,需要執行擴容然後對於hash表中的元素重新對映完成遷移。這項工作的開銷往往比較大,故在這種場景下,可以適用動態hash演算法。

動態hash的原理如下圖所示,hash表大小為1在hash表擴容方面,動態hash優越於傳統hash的地方在於動態hash表的元素遷移只會涉及到某乙個block上的元素,其他block上的元素不用遷移。在原理上,hash函式值為固定位數(32位或64位),其利用hash函式值的後table_prefix位來決定元素存放的block號。在table擴容的過程中,對稱表項指向相同的block,這樣具有相同字尾hash函式值的元素會對映到同乙個block上。

當某乙個block上的元素達到設定的上限數目時,再次向此block插入元素會導致hash表擴容,動態hash表擴容的場景可分為兩類:

一、只有乙個表項指向這個block,此時table_prefix== block_prefix。這時需要針對table擴容,即table_prefix++,table的大小加倍。然後對稱表項指向相同的block,需要插入元素的block進行元素遷移,也就是因為現在table_prefix比原來要大,元素分配block更精確了。這樣原先block上會騰出空位,放入新插入的元素即可。需要遷移的元素另外組成乙個block,讓對稱的表項指向新的block,相應地,由於指向block的表項數減少了,block_prefix也要增加,即block_prefix++。但是可能存在元素都不會遷移的場景,也就是說這時block中所有元素的後table_prefix位還是相同的。這時分兩種情況,一是如果所有元素的hash函式值都相同,那麼通過擴容增加table的大小是無濟於事的,因為它們始終對映到同乙個block,這時就需要在原先block的基礎上增加乙個溢位桶用來存放新插入的元素。二是此時的table_prefix還不夠大,需要進一步加大table_prefix判斷元素遷移的block號,這種情況就需要重複上述步驟。

二、多個表項同時指向這個block,此時table_prefix> block_prefix。這時還不需要進行擴容,只需要進行元素遷移,遷移過程與情況一相同。

針對上述hash原理,設計出的hash表結構圖如圖所示,每個block會有乙個item_t表項來記錄block的相關資訊,ref_count為引用計數,用來標識指向block的表項數目,控制block元素的釋放,block帶有next指標用於標識溢位桶。item中的hash_prefix就是上面說的block_prefix,table中的hash_prefix就是上面說的table_prefix。

整個hash表操作涉及到插入、刪除、查詢,具體函式的實現見源**。

dhash_t*dhash_init(int block_len)

初始化構造dhash_t結構體,用於表示動態hash表,初始化成功返回dhash_t例項,否則返回null。

voiddhash_destroy(dhash_t *dhash)

銷毀動態hash表,釋放hash表記憶體,執行一些清理工作。

voidset_hash_func(dhash_t *dhash, hash_func_t func)

voidset_free_elem_func(dhash_t *dhash, free_elem_func_t func)

voidset_elem_equal_func(dhash_t *dhash, elem_equal_func_t func)

voidset_copy_elem_func(dhash_t *dhash, copy_elem_func_t func)

voidset_show_elem_func(dhash_t *dhash, show_elem_func_t func)

分別為動態hash表設定hash函式指標、元素釋放指標、判斷元素相等函式指標、拷貝元素函式指標、列印hash表函式指標。

elem_t*dhash_query(dhash_t *dhash, elem_t elem)

在hash表中查詢指定元素,存在則返回元素指標,否則返回null。

intdhash_insert(dhash_t *dhash, elem_t elem)

在hash表中插入指定元素,成功返回0,否則返回-1。

intdhash_delete(dhash_t *dhash, elem_t elem)

在hash表中刪除指定元素,成功返回0,否則返回-1。

voiddhash_show(dhash_t *dhash)

列印hash表中所有的元素。

talk is cheap, show me the code。動態hash演算法的c實現原始碼已託管至github,見

如果覺得還不錯的話,fork和star是對作者寫作的最大支援。

hash表 hash演算法

概念 雜湊表 hash table。也叫雜湊表 是依據關鍵碼值 key value 而直接進行訪問的 資料結構。也就是說,它通過把關鍵碼值對映到表中乙個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做雜湊表。給定表m,存在函式f key 對隨意給定的keyword值ke...

VC中實現雜湊Hash演算法

vc中實現雜湊hash演算法 2012 03 23 10 16 35 我來說兩句 收藏 我要投稿 字型 小大 hash函式我們可以自己用c來編寫,但是如果在vc中就不必了,因為在vc中有實現hash演算法的 函式可以呼叫,就是cryptacquirecontext函式,這個函式的定義在wincryp...

hash位址 Hash演算法基礎

hash,一般翻譯做 雜湊 也有直接音譯為 雜湊 的,就是把任意長度的輸入,通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出,所以不可能從雜湊值來唯一的確定輸入值。簡單的說就是一種將任意長度的訊...