簡單好用的hash表-----uthash


在軟件開發中,不可不免的會使用到hash表,hash表的優點這里就不說了,以下介紹一個hash表的C實現,

uthash是用宏實現的,使用的時候非常方便,只用包含uthash.h即可。

Uthash的三個數據結構:

typedef struct UT_hash_bucket {

   struct UT_hash_handle *hh_head;

   unsigned count;

   unsigned expand_mult;

} UT_hash_bucket;

UT_hash_bucket作用提供根據hash進行索引。

typedef struct UT_hash_table {

   UT_hash_bucket *buckets;

   unsigned num_buckets, log2_num_buckets;

   unsigned num_items;

   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */

   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ 

   unsigned ideal_chain_maxlen;
   unsigned nonideal_items;             
   unsigned ineff_expands, noexpand;
   uint32_t signature; /* used only to find hash tables in external analysis */

#ifdef HASH_BLOOM
   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
   uint8_t *bloom_bv;
   char bloom_nbits;
#endif

} UT_hash_table;

UT_hash_table可以看做hash表的表頭。

typedef struct UT_hash_handle {

  struct UT_hash_table *tbl;

  void *prev; /* prev element in app order */
  void *next; /* next element in app order */

  struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
  struct UT_hash_handle *hh_next; /* next hh in bucket order */

  void *key;      /* ptr to enclosing struct's key */

  unsigned keylen;  /* enclosing struct's key len */
  unsigned hashv;   /* result of hash-fcn(key) */

} UT_hash_handle;

UT_hash_handle,用戶自定義數據必須包含的結構。

三種數據結構的關系如下:

 

說明:

每一個節點(用戶自定義的)必須包含一個UT_hash_handle hh

key:用戶自定義,可以是int, string和指針。

hh_prev: 指向前一個UT_hash_handle 

hh_next: 指向下一個UT_hash_handle

hashv:根據key計算出的hash

prev: 指向前一個數據節點(Hash沖突時)

next: 指向下一個數據節點(Hash沖突時)

hho: 數據節點中hh於用戶節點首地址的差。

 

uthash使用代碼例子

#include "uthash.h"  
#include <stdlib.h>   /* malloc */  
#include <stdio.h>    /* printf */  
#include <time.h>  

typedef struct example_user_t {  
    int id;  
    int cookie;  
    UT_hash_handle hh;  
} example_user_t;  
  
int main(int argc,char *argv[]) {  
    int i;  
    example_user_t *user, *users=NULL;  
  
    srand((unsigned int)time(NULL));  
    /* create elements */  
    for(i=0;i<10;i++) {  
        if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-1);  
        user->id = rand()%100;  
        user->cookie = i*i;  
        HASH_ADD_INT(users,id,user);  
    }  
  
    for(user=users; user != NULL; user=(example_user_t*)(user->hh.next)) {  
        printf("user %d, cookie %d\n", user->id, user->cookie);  
    }  
   return 0;  
}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM