動態hashtable的C語言實現

    由於C語言中缺乏像C++中的數據容器,所以用C語言自己對hashtable做了一個前期的原理分析及函數定義,以備自己以後查用。字符串的hash處理採用lua源碼中的luaS_hash函數。

hash數據存儲模塊:(只支持一對一的table結構,如果兩個key值一模一樣則更新表中數據)

hash數據結構:
struct hash_value {
  union{
    uint32_t k_num;
    char k_char[32];       //最大支持32個字節的key值長度 
  }key;
  void * data;             //數據存儲位置
  struct hash_value *next; //同一個hash值的數據存儲鏈表
};
typedef struct hash_tab {
  struct hash_value ** hash;
  uint32_t nuse;   //hashtab中已插入的數據條數
  uint32_t size;   //當前hashtab的大小。
}hash_tab;


通過採用key-value的方式,key支持int,string類型數據,value爲void*類型。hash函數採用luaS_hash函數原型。
提供創建:       hash_create(hash_tab *tab, uint32_t size)
    修改tab大小:hash_resize(hash_tab *tab, uint32_t newsize)
    插入:       hash_insert(hash_tab *tab, char *key, void *data)
    刪除:       hash_remove(hash_tab *tab, char *key, void *data)   
    查找:        hash_value(hash_tab *tab, char *key)
    清除:       hash_destroy(hash_tab *tab)
擴展接口:(支持插入重複key值的數據,用來實現key值一對多的hashtable)
    插入:       hash_mult_insert(hash_tab *tab, char *key, void *data)
    刪除:       hash_remove(hash_tab *tab, char *key, void *data)
    查找:        hash_values(hash_tab *tab, char *key)
    
hash表實現原理:
    1,初始化一個固定大小的hashtable。例如1024大小。
    2,當有一個數據插入進來時,調用luaS_hash計算作爲key值的字符串的hash值。
    3,將計算出來的hash值對整個table大小取模,然後將數據存儲到取模後table中對應位置的數據鏈表裏面。
    4,如果已插入的數據條數已經達到當前table的大小,則將table的大小翻一倍。將table中的所有hash節點清空。
    5,重新計算以前table中的所有數據的hash值,並重新存儲到table表的相應位置。修改table表的大小。
hash表數據查找:
    1,將傳入的key值調用luaS_hash計算對應的hash值,
    2,將hash值取模得到對應的table表位置,然後循環數據鏈表中的數據對key值進行比較。取出匹配到的數據指針。
    
備註:如果是int型的key值,可以不做luaS_hash處理,直接對key值進行取模及之後的數據存取操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章