深入解讀Khash h之資料結構

2021-10-04 12:31:29 字數 2436 閱讀 6328

閱讀此文前,推薦先看klib之khash學習筆記

c語言標準庫並沒有字典(map)和集合(set)這種資料結構,因此如果想需要在c語言使用這種資料結構,要麼自己根據不同資料型別都寫一種函式,或者就是用別人寫好的資料結構來用。

khash.h提供了一種基於開放定址法的泛型的雜湊表, 這裡的開放定址法是一種解決雜湊衝突的方法,當雜湊函式時計算的位置已經有元素的時候,它會基於當前位置往後探測(probe), 找到一處沒有元素的位置。當然還有一種方法,就是拉鍊法,也就是在衝突的地方,建立乙個鍊錶,裡面存放具有相同雜湊位址的不同元素。

khash.h根據不同的初始化函式會替換成不同的雜湊函式,一共有是那種int,int64str

#define kh_int_hash_func(key) (khint32_t)(key)

#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)

#define kh_str_hash_func(key) __ac_x31_hash_string(key)

int就是將原值轉換成khint32_tint64用到了位運算,通過右移,按位異或和左移操作,最後轉換成khint32_t。這兩個雜湊函式都非常簡單,降低了雜湊函式計算的時間。

稍微複雜的就是字串的雜湊函式, 它的計算方式如下

static kh_inline khint_t __ac_x31_hash_string(const char *s)

此外還有乙個在2011-09-16 (0.2.6)增加的雜湊函式kh_int_hash_func2, 能夠比較好的處理一些不怎麼隨機的資料,它的計算過程就非常的複雜了,預設不啟用,。

static kh_inline khint_t __ac_wang_hash(khint_t key)

#define kh_int_hash_func2(key) __ac_wang_hash((khint_t)key)

資料結構通常和演算法都是搭配使用,因此理解這個資料結構的設計,就能理解後續的**邏輯。

khash.h的定義的kh_##name##_t資料結構一共有7個部分

#define __khash_type(name, khkey_t, khval_t) \

typedef struct kh_##name##_s kh_##name##_t;

關於桶的大小n_buckets:作者以2的n次方大小,保證有足夠的空間,降低雜湊碰撞。

關於sizen_occupied: 之所以有兩個變數來記錄雜湊表中的元素,是為了降低刪除運算。我們不需要在每一次刪除運算時,都進行記憶體的釋放和調整,而只要將對應的位置標記為刪除狀態即可,也就是減少size,而不減少n_occupied.

關於上限upper_bound: 當桶剩下的空間不夠時,那麼出現雜湊碰撞的概率就會變大,因此就需要對雜湊表進行調整,計算公式如下。

tatic const double __ac_hash_upper = 0.77;

h->upper_bound = (khint_t)(h->n_buckets * __ac_hash_upper + 0.5);

剩下的flags,keysvals都是指標,用於指向實際位址,是實際記錄資料型別的資料結構。

new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t));

memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t));

khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t));

khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t));

如下是資料結構的示意圖

資料結構示意圖

具體的賦值和刪除操作,在後續介紹。

C語言 深入解讀資料結構之堆的實現

概念 如果有乙個關鍵碼的集合k 把它的所有元素按完全二叉樹的順序儲存方式儲存 在乙個一維陣列中,並滿足k i k 2 i 1且ki k 2程式設計客棧 i 2 k i k 2 i 1且ki k 2 i 2 i 0,1,2.則稱為小堆 或大堆 將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小...

多層LSTM結構的深入解讀

讀這篇文章的時候,預設你已經對lstm神經網路有了乙個初步的認識,當你深入理解時,可能會對多層lstm內部的隱藏節點數,有關cell的定義或者每一層的輸入輸出是什麼樣子的特別好奇,雖然神經網路就像是乙個黑箱子一樣,但是我們仍然試圖去理解他們。我們所說的lstm的cell就是這樣子的乙個結構 圖中標識...

資料結構之深入理解紅黑樹

本文將會透徹理解什麼是紅黑樹,有什麼特點 優點與缺點,與其它樹結構 二叉查詢樹 平衡二叉樹 2 3 4樹 有什麼區別和聯絡。寫作本文的目的旨在加深自己的理解,文中許多內容參考了網路上的文章並根據自己的理解進行了整理。紅黑樹 英語 red black tree 一種二叉查詢樹,但在每個結點上增加乙個儲...