哈希表(C语言实现)超级简洁版

数据结构设计

//字典类型
#define DICT_TYPE_INT 0
#define DICT_TYPE_STR 1

//键值对
typedef struct dict_entry
{
	struct dict_entry* next;
	void* key;
	void* value;
}dict_entry;

typedef struct dict
{
	//哈希函数
	unsigned int (*hash)(void* key);
	// table 数组存放 dict_entry 指针
	dict_entry** table;
	int size;
	//掩码
	int sizemask;
}dict;

接口设计

//哈希函数(适用整数)
static unsigned int hash_integer(void* key);
//哈希函数(适用字符串)
static unsigned int hash_33(void* key);
//创建一个dict
dict* dict_create(int type);
//创建一个dict_entry
dict_entry* dict_create_entry(void* key, void* value);
//字典插入一个键值对
dict* dict_put_entry(dict* dict, void* key, void* value);
//dict获取值
void* dict_get_value(dict* dict, void* key);
//清除所有dict元素
void dict_empty(dict* dict);
//释放dict
void dict_release(dict* dict);

接口实现

/哈希函数(适用整数)
static unsigned int hash_integer(void* key)
{
	return (*(int*)key * 2654435769) >> 28;
}

//哈希函数(适用字符串)
static unsigned int hash_33(void* key)
{
	unsigned int hash = 0;
	while (*(char*)key!=0)
	{
		//左移5位相当于*32,再加hash相当于*33
		hash = (hash << 5) + hash + (*(char*)key)++;
	}
	return hash;
}

//创建一个dict
dict* dict_create(int type)
{
	dict* dict = (struct dict*)malloc(sizeof(struct dict));
	if (dict == NULL)
		return NULL;
	if (type == DICT_TYPE_INT)
		dict->hash = &hash_integer;
	else
		dict->hash = &hash_33;

	dict->size = 1;
	dict->sizemask = dict->size - 1;
	dict->table = (dict_entry**)malloc(sizeof(dict_entry*) * (dict->size));
	if (dict->table == NULL)
		return NULL;
	memset(dict->table, 0, sizeof(dict_entry*) * (dict->size));
	return dict;
}

//创建一个dict_entry
dict_entry* dict_create_entry(void* key, void* value) 
{
	dict_entry* entry = (struct dict_entry*)malloc(sizeof(struct dict_entry));
	if (entry == NULL)
		return NULL;
	entry->key = key;
	entry->value = value;
	entry->next = NULL;
	return entry;
}

//字典插入一个键值对
dict* dict_put_entry(dict* dict, void* key, void* value)
{
	//无论key值是否存在都直接新插入 key - value
	unsigned int hash = dict->hash(key);
	int pos = hash & dict->sizemask;

	dict_entry* entry;
	entry = dict_create_entry(key,value);
	entry->next = dict->table[pos];
	dict->table[pos] = entry;

	return dict;
}

/*
dict* dict_put_entry1(dict* dict, void* key, void* value)
{
	//检查 key 值是否存在,存在则跟新 value 值
	unsigned int hash = dict->hash(key);
	int pos = hash & dict->sizemask;
	dict_entry* entry, * cur;
	
	if (dict->table[pos] == 0)
	{
		printf("新增\n");
		entry = dict_create_entry(key, value);
		dict->table[pos] = entry;
	}
	else
	{
		cur = dict->table[pos];

		if (dict->hash(cur->key)==dict->hash(key))
		{
			printf("更新\n");
			cur->value = value;
			return dict;
		}

		//如果不符合,则继续遍历查找,找到结尾尾插入即可
		while (cur->next!=NULL)
		{
			printf("往下找\n");
			if (dict->hash(cur->next->key)==dict->hash(key))
			{
				printf("更新\n");
				cur->next->value = value;
				return dict;
			}
			cur = cur->next;
		}
		printf("尾部插入\n");
		entry = dict_create_entry(key, value);
		cur->next = entry;
	}
	return dict;
}
*/

//dict获取值
void* dict_get_value(dict* dict, void* key)
{
	unsigned int hash = dict->hash(key);
	int pos = hash & dict->sizemask;
	if (dict->table[pos] == NULL)
		return NULL;
	dict_entry* cur = dict->table[pos];
	while (dict->hash(cur->key) != dict->hash(key))
	{
		if (cur->next != NULL)
			cur = cur->next;
		else
			return NULL;
	}
	return cur->value;
}

//清除所有dict元素
void dict_empty(dict* dict)
{
	for (int i = 0; i < dict->size; i++)
	{
		if (dict->table[i]!=0)
		{
			dict_entry* cur, * next;
			cur = dict->table[i];
			while (cur)
			{
				next = cur->next;
				free(cur);
				cur = next;
			}
			dict->table[i] = 0;
		}//end if
	}//end for
	return ;
}

//释放dict
void dict_release(dict* dict)
{
	dict_empty(dict);
	free(dict->table);
	free(dict);

	return;
}

测试代码

int main()
{
	//创建一个key为字符串的字典
	dict* dict = dict_create(1);

	char str[] = "name";
	char str2[] = "Austin";
	char str3[] = "Lookcos";
	char str4[] = "age";
	int age = 18;

	dict_put_entry(dict, &str4, &str2);
	printf("%s\n", (char*)dict_get_value(dict, &str4));

	dict_put_entry(dict, &str2, &str);
	printf("%s\n", (char*)dict_get_value(dict, &str2));

	dict_put_entry(dict, &str, &str3);
	printf("%s\n", (char*)dict_get_value(dict, &str));

	dict_put_entry(dict, &str4, &age);
	printf("age: %d\n", *(int*)dict_get_value(dict, &str4));

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值