Hash表的基本实现

#include"common.h"
#include"hash.h"

typedef struct hash_node
{
	void *key;              //key值
	void *value;            //value值
	struct hash_node *prev; //前驱
	struct hash_node *next; //后继
} hash_node_t;

struct hash
{
	unsigned int buckets;   //桶的大小
	hashfunc_t hash_func;   //哈希函数
	hash_node_t **nodes;    //数组空间
};

hash_node_t** hash_get_bucket(hash_t *hash, void *key);
hash_node_t* hash_get_node_by_key(hash_t *hash, void *key, unsigned int key_size);

//申请
hash_t *hash_alloc(unsigned int buckets, hashfunc_t hash_func)//申请
{
	hash_t *hash = (hash_t *)malloc(sizeof(hash_t));
	assert(hash != NULL);
	hash->buckets = buckets;
	hash->hash_func = hash_func;
	int size = buckets * sizeof(hash_node_t *);
	hash->nodes = (hash_node_t **)malloc(size);
	memset(hash->nodes, 0, size);
	return hash;
}
//查询
void* hash_lookup_entry(hash_t *hash, void* key, unsigned int key_size)
{
	hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
	if (node == NULL)
	{
		return NULL;
	} 
	return node->value;
}
//插入
void hash_add_entry(hash_t *hash, void *key, unsigned int key_size,void *value, unsigned int value_size)
{
	if (hash_lookup_entry(hash, key, key_size)) 
	{
		fprintf(stderr, "duplicate hash key\n");
		return;
	} 
	hash_node_t *node = malloc(sizeof(hash_node_t));
	node->prev = NULL;
	node->next = NULL;
	node->key = malloc(key_size);
	memcpy(node->key, key, key_size);
	node->value = malloc(value_size);
	memcpy(node->value, value, value_size);
	hash_node_t **bucket = hash_get_bucket(hash, key);
	if (*bucket == NULL)
	{
		*bucket = node;
	} 
	else
	{
		// 将新结点插入到链表头部(效率高
		node->next = *bucket;
		(*bucket)->prev = node;
		*bucket = node;
	}
}
//删除
void hash_free_entry(hash_t *hash, void *key, unsigned int key_size)
{
	hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
	if (node == NULL)
	{
		return;
	} 
	free(node->key);
	free(node->value);
	if (node->prev)
	{
		node->prev->next = node->next;
	}
	else
	{
		hash_node_t **bucket = hash_get_bucket(hash, key);
		*bucket = node->next;
	} 
	if(node->next)
		node->next->prev = node->prev;
	free(node);
}
//获取桶节点
hash_node_t** hash_get_bucket(hash_t *hash, void *key)
{
	unsigned int bucket = hash->hash_func(hash->buckets, key);
	if (bucket >= hash->buckets)
	{
		fprintf(stderr, "bad bucket lookup\n");
		exit(EXIT_FAILURE);
	} 
	return &(hash->nodes[bucket]);
}
//通过key值找到节点
hash_node_t* hash_get_node_by_key(hash_t *hash, void *key, unsigned int key_size)
{
	hash_node_t **bucket = hash_get_bucket(hash, key);
	hash_node_t *node = *bucket;
	if (node == NULL)
	{
		return NULL;
	}
	while (node != NULL && memcmp(node->key, key, key_size) != 0)
	{
		node = node->next;
	}
	return node;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值