C函数学习:uthash哈希表
Posted Stoneshen1211
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C函数学习:uthash哈希表相关的知识,希望对你有一定的参考价值。
文章目录
1 哈希表简介
哈希表是一种基于key-value进行访问的数据结构,可以加快查找的速度,因此在一些需要快速查找是否有重复元素的场景中,常常使用哈希表来实现。
2 uthash
C语言中不存在哈希,如果自己构建则会很麻烦。第三方开源的代码中已经实现哈希表,因此我们在使用中只需要包含头文件“uthash.h”即可使用第三方的哈希功能。
PS:uthash还包括三个额外的头文件,主要提供链表,动态数组和字符串。utlist.h为C结构提供了链接列表宏。utarray.h使用宏实现动态数组。utstring.h实现基本的动态字符串。
下载链接:https://github.com/troydhanson/uthash
文档说明:http://troydhanson.github.io/uthash/userguide.html#_find_item
2.1 定义结构体
在使用时候我们需要先定义一个结构体。如下:
typedef struct _HashTable_
int s32Key; //key
int s32Value;
UT_hash_handle hh;
HastTableST;
在上面的结构体中,s32Key就是键;
s32Value是我们自定义的值,用来存放私有的数据,可以根据自己的需要定义;
hh是内部使用的hash处理句柄,在使用过程中,只需要在结构体中定义一个UT_hash_handle类型的变量即可,不需要为该句柄变量赋值,但必须在该结构体中定义该变量。
键的类型不一定是int类型,也可以是字符串类型,指针类型和任意类型,不同类型的键在下面插入,查找使用的函数宏是不一样的。
2.2 键类型为int
2.2.1 插入
HASH_ADD_INT
2.2.2 查找
HASH_FIND_INT
2.2.3 删除
HASH_DEL
2.2.4 替换
HASH_REPLACE_INT
2.2.5 计数
HASH_COUNT
2.2.6 遍历
HASH_ITER
2.2.7 示例
#include <stdio.h>
//#include "uthash.h"
typedef struct _HashTable_
int s32Key;
int s32Index; //用户自定义的值
UT_hash_handle hh;
HastTableST;
//清除单个
void hash_clearsingle(HastTableST* pstHash, HastTableST* pstDelHash)
HASH_DEL(pstHash, pstDelHash);
free(pstDelHash);
pstDelHash = NULL;
//清除全部
void hash_clearall(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
HASH_DEL(pstHash, s);
free(s);
s = NULL;
//查找
HastTableST* hash_find(HastTableST* pstHash, int s32Key)
HastTableST* pstTmpHash = NULL;
HASH_FIND_INT(pstHash, &s32Key, pstTmpHash);
return pstTmpHash;
//添加
void hash_add(HastTableST* pstHash, int s32KKey)
HastTableST* pstTmpHash = NULL;
pstTmpHash = hash_find(pstHash, s32KKey); //先查找key是否存在哈希表中
if (NULL == pstTmpHash)
pstTmpHash = (HastTableST *)malloc(sizeof(HastTableST));
pstTmpHash->s32Key = s32KKey;
HASH_ADD_INT(pstHash, s32Key, pstTmpHash);
else //存在
//替换
//HASH_REPLACE_INT
//计数
int hash_count(HastTableST* pstHash)
return HASH_COUNT(pstHash);
//遍历
void hash_iter(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
printf("user id %d\\n", s->s32Key);
/* ... it is safe to delete and free s here */
int main()
return 0;
2.3 键类型为字符串
除了查找(HASH_FIND_STR)和添加( HASH_ADD_KEYPTR),其它函数一致。
示例:
#include <stdio.h>
//#include "uthash.h"
typedef struct _HashTable_
char* s8Name;
int s32Index; //用户自定义的值
UT_hash_handle hh;
HastTableST;
//清除单个
void hash_clearsingle(HastTableST* pstHash, HastTableST* pstDelHash)
HASH_DEL(pstHash, pstDelHash);
free(pstDelHash);
pstDelHash = NULL;
//清除全部
void hash_clearall(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
HASH_DEL(pstHash, s);
free(s);
s = NULL;
//查找
HastTableST* hash_find(HastTableST* pstHash, char* s8Key)
HastTableST* pstTmpHash = NULL;
HASH_FIND_STR(pstHash, s8Key, pstTmpHash);
return pstTmpHash;
//添加
void hash_add(HastTableST* pstHash, char* s8Key)
HastTableST* pstTmpHash = NULL;
pstTmpHash = hash_find(pstHash, s8Key); //先查找key是否存在哈希表中
if (NULL == pstTmpHash)
pstTmpHash = (HastTableST *)malloc(sizeof(HastTableST));
pstTmpHash->s8Name = s8Key;
HASH_ADD_KEYPTR(hh, pstHash, pstTmpHash->s8Name, strlen(pstTmpHash->s8Name), pstTmpHash);
else //存在
//替换
//HASH_REPLACE_INT
//计数
int hash_count(HastTableST* pstHash)
return HASH_COUNT(pstHash);
//遍历
void hash_iter(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
printf("user id %s\\n", s->s8Name);
/* ... it is safe to delete and free s here */
int main()
return 0;
2.4 键类型为指针
除了添加(HASH_ADD_PTR)和查找( HASH_FIND_PTR),其它函数一致。
示例:
#include <stdio.h>
//#include "uthash.h"
typedef struct _HashTable_
void* pKey;
int s32Index; //用户自定义的值
UT_hash_handle hh;
HastTableST;
//清除单个
void hash_clearsingle(HastTableST* pstHash, HastTableST* pstDelHash)
HASH_DEL(pstHash, pstDelHash);
free(pstDelHash);
pstDelHash = NULL;
//清除全部
void hash_clearall(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
HASH_DEL(pstHash, s);
free(s);
s = NULL;
//查找
HastTableST* hash_find(HastTableST* pstHash, void* pFindKey)
HastTableST* pstTmpHash = NULL;
HASH_FIND_PTR(pstHash, &pFindKey, pstTmpHash);
return pstTmpHash;
//添加
void hash_add(HastTableST* pstHash, void* pFindKey)
HastTableST* pstTmpHash = NULL;
pstTmpHash = hash_find(pstHash, pFindKey); //先查找key是否存在哈希表中
if (NULL == pstTmpHash)
pstTmpHash = (HastTableST *)malloc(sizeof(HastTableST));
pstTmpHash->pKey = pFindKey;
HASH_ADD_PTR(pstHash, pKey, pstTmpHash);
else //存在
//替换
//HASH_REPLACE_INT
//计数
int hash_count(HastTableST* pstHash)
return HASH_COUNT(pstHash);
//遍历
void hash_iter(HastTableST* pstHash)
HastTableST *s, *tmp;
HASH_ITER(hh, pstHash, s, tmp)
printf("user id %d\\n", s->s32Key);
/* ... it is safe to delete and free s here */
int main()
return 0;
2.5 键类型为任意类型
参考链接:http://troydhanson.github.io/uthash/userguide.html#_structure_keys
以上是关于C函数学习:uthash哈希表的主要内容,如果未能解决你的问题,请参考以下文章