在软件开发中,不可不免的会使用到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=;i<;i++) {
if ( (user = (example_user_t*)malloc(sizeof(example_user_t))) == NULL) exit(-);
user->id = rand()%;
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 ;
}

最新文章

  1. OOAD利器之UML基础
  2. 枚举/遍历 一个数组NSArray/NSDictionary
  3. C#—WebService
  4. VIM如何将全部内容复制并粘贴到外部
  5. ExtJS 的一些技巧与问题
  6. 处理日期时间NSDate
  7. jQuery进行DOM操作记录
  8. 【CF493E】【数学】Vasya and Polynomial
  9. 小tip:我是如何初体验uglifyjs压缩JS的
  10. mysql出现错误“ Every derived table must have its own alias”
  11. c语言 选择排序
  12. 对于面向对象的理解(JAVA)
  13. app每个页面都有一个相同的浮层控件 实现思路
  14. 67. Add Binary【LeetCode】
  15. OC可点击的两种轮播图效果
  16. linux内核 container_ofC语言之应用
  17. 【译】《Clean C#》
  18. CenterOS7.5中搭建wordpress
  19. Java第三阶段学习(十、XML学习)
  20. SharePoint Designer 配置工作流后需要重启的问题

热门文章

  1. GIS+=地理信息+容器技术(4)——Docker执行
  2. 建立与读取.ini文件
  3. java各种框架的比较,分析
  4. sp_trace_setevent sqlserver跟踪事件及列
  5. 用JS实现任意导航栏的调用
  6. python中如何对list之间求交集,并集和差集
  7. oc字符串的用法
  8. libXext.so.6 libXp.so.6 libXt.so.6 is needed by openmotif21-2.1.30-11.el7.i686
  9. 【转】对 Go 语言的综合评价
  10. AOE网与关键路径简介