哈希桶实现

10 篇文章 0 订阅
8 篇文章 0 订阅

参考博客:哈希表+哈希桶简介及实现

参考的另一篇博客,将他的代码稍微改了改拿来用。

哈希桶,听名字不知道是什么,看完本质就是用链地址法来解决哈希冲突。
至于hash函数,这个作者用的应该是直接定址法。书上一般都说除留余数法用的多一点。

(编译遇到问题的,麻烦用.c后缀而不是.cpp后缀,两个语法有差别。)

#define _XOPEN_SOURCE 500

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define BUCKET_COUNT 10

typedef struct Node {
	char *key;
	char *value;
	struct Node *next;
} Node;

typedef struct hashTable {
	Node bucket[BUCKET_COUNT];
} hashTable;


void
init_hash_table (hashTable *t)
{
	if (t == NULL)
		return;
	for (int i = 0 ; i < BUCKET_COUNT; ++i) {
		t->bucket[i].key = NULL;
		t->bucket[i].next = NULL;
		t->bucket[i].value = NULL;
	}
}

int
hash (const char *key)
{
	int hash = 0;
	for (; *key != '\0'; ++key) {
		hash = hash * 33 + *key;
	}
	return hash % BUCKET_COUNT;
}

int
insert_node (hashTable *t, char *key, char *value)
{
	if (t == NULL || key == NULL || value == NULL)
		return -1;
		
	int index = hash (key);
	if (t->bucket[index].key == NULL) {//如果桶为空,则直接写入第一个桶节点
		t->bucket[index].key = strdup (key);
		t->bucket[index].value = strdup (value);
	} else {
		Node *curr, *prev;
		curr = prev = & (t->bucket[index]);
		while (curr != NULL) {
			if (strcmp (curr->key, key) == 0) {//如果key值重复,替换相应的值
				free (curr->value);
				curr->value = strdup (value);
			}
			prev = curr;
			curr = curr->next;
		}
		//没有在当前桶中找到。创建新的节点,并加入桶链表
		curr = malloc (sizeof (Node));
		*curr = (Node) {
			.key = strdup (key),
			.value = strdup (value),
			.next = NULL
		};
		prev->next = curr;
	}
	return index;
}

void
print_hash_table (hashTable *t)
{
	if (t == NULL)
		return;
	for (int i = 0; i < BUCKET_COUNT ; ++i) {
		printf ("bucket[%d]:", i);
		Node *bucket = & (t->bucket[i]);
		while (bucket != NULL) {
			printf ("%s = %s\t\t", bucket->key, bucket->value);
			bucket = bucket->next;
		}
		putchar ('\n');
	}
}

int main (int argc, char *argv[])
{
	hashTable *ht;
	ht = malloc (sizeof (hashTable));
	init_hash_table (ht);
	char *key[] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
	               "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
	               "u", "v", "w", "x", "y", "z"
	              };
	char *value[] = {"apple", "banana", "china", "doge", "egg", "fox",
	                 "goat", "hello", "ice", "jeep", "key", "love",
	                 "mirror", "net", "orange", "panda", "quarter", "rabbit",
	                 "shark", "tea", "unix", "volley", "wolf", "x-ray", "yard", "zoo"
	                };
	for (int i = 0; i < 26; ++i) {
		insert_node (ht, key[i], value[i]);
	}
	print_hash_table (ht);
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

barbyQAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值