#include <stdlib.h>
#include <string.h>
// 哈希表节点结构
typedef struct HashNode {
char *key; // 键(字符串类型)
int value; // 值(整数类型)
struct HashNode *next; // 链表指针
} HashNode;
// 哈希表主体结构
typedef struct {
HashNode **buckets; // 桶数组
int capacity; // 总容量
int size; // 当前元素数
} HashMap;
// 哈希函数(djb2算法)
unsigned long hash_func(const char *str) {
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; // hash * 33 + c
return hash;
}
// 创建哈希表
HashMap* hashmap_create(int init_capacity) {
HashMap *map = (HashMap*)malloc(sizeof(HashMap));
map->capacity = init_capacity;
map->size = 0;
map->buckets = (HashNode**)calloc(init_capacity, sizeof(HashNode*));
return map;
}
// 扩容哈希表
static void resize(HashMap *map, int new_capacity) {
HashNode **new_buckets = (HashNode**)calloc(new_capacity, sizeof(HashNode*));
// 重新哈希所有元素
for (int i = 0; i < map->capacity; i++) {
HashNode *node = map->buckets[i];
while (node) {
HashNode *next = node->next;
unsigned long idx = hash_func(node->key) % new_capacity;
node->next = new_buckets[idx];
new_buckets[idx] = node;
node = next;
}
}
free(map->buckets);
map->buckets = new_buckets;
map->capacity = new_capacity;
}
// 插入键值对
void hashmap_put(HashMap *map, const char *key, int value) {
// 自动扩容(负载因子 > 0.75)
if (map->size * 4 > map->capacity * 3) {
resize(map, map->capacity * 2);
}
unsigned long idx = hash_func(key) % map->capacity;
HashNode **head = &map->buckets[idx];
// 检查是否已存在相同key
while (*head) {
if (strcmp((*head)->key, key) == 0) {
(*head)->value = value;
return;
}
head = &(*head)->next;
}
// 创建新节点
HashNode *new_node = (HashNode*)malloc(sizeof(HashNode));
new_node->key = strdup(key); // 复制key字符串
new_node->value = value;
new_node->next = map->buckets[idx];
map->buckets[idx] = new_node;
map->size++;
}
// 查找键值
int hashmap_get(HashMap *map, const char *key, int *found) {
unsigned long idx = hash_func(key) % map->capacity;
HashNode *node = map->buckets[idx];
while (node) {
if (strcmp(node->key, key) == 0) {
if (found) *found = 1;
return node->value;
}
node = node->next;
}
if (found) *found = 0;
return 0;
}
// 删除键值对
int hashmap_remove(HashMap *map, const char *key) {
unsigned long idx = hash_func(key) % map->capacity;
HashNode **head = &map->buckets[idx];
while (*head) {
if (strcmp((*head)->key, key) == 0) {
HashNode *to_delete = *head;
*head = (*head)->next;
free(to_delete->key);
free(to_delete);
map->size--;
return 1;
}
head = &(*head)->next;
}
return 0;
}
// 销毁哈希表
void hashmap_destroy(HashMap *map) {
for (int i = 0; i < map->capacity; i++) {
HashNode *node = map->buckets[i];
while (node) {
HashNode *next = node->next;
free(node->key);
free(node);
node = next;
}
}
free(map->buckets);
free(map);
}
// 示例用法
#include <stdio.h>
int main() {
HashMap *map = hashmap_create(8);
// 插入数据
hashmap_put(map, "apple", 42);
hashmap_put(map, "banana", 17);
// 查找数据
int found;
int val = hashmap_get(map, "apple", &found);
if (found) {
printf("apple: %d\n", val); // 输出 apple: 42
}
// 删除数据
hashmap_remove(map, "banana");
hashmap_destroy(map);
return 0;
}