参考博客:哈希表+哈希桶简介及实现
参考的另一篇博客,将他的代码稍微改了改拿来用。
哈希桶,听名字不知道是什么,看完本质就是用链地址法来解决哈希冲突。
至于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;
}