C函数学习(1):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),其它函数一致。

示例:

扫描二维码关注公众号,回复: 15272538 查看本文章
#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

猜你喜欢

转载自blog.csdn.net/u011003120/article/details/124986557
今日推荐