用C语言实现哈希表HashMap

本文介绍了用C语言实现的一个自定义HashMap,它支持动态扩容,采用了类似Java8HashMap的扩容策略,使用murmur_hash2作为哈希函数,详细描述了关键操作如创建、存入、查询和删除键值对的实现原理和代码片段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码仓库地址

1. 功能说明
  • 自定义初始容量和负载因子;
  • 当键值对的个数与容量比值超过负载因子时,自动扩容;
  • 借鉴Java8的HashMap部分扩容逻辑,定义了单独的桶结构体用于记录hash值,以及2倍扩容,减少了hash运算和移位的开销。
2. 实现原理

采用动态数组加链表的方式实现(之后撸完红黑树,增加动态数组+链表+红黑树的版本)。

在这里插入图片描述

3. 定义头文件
#ifndef HASH_MAP_H
#define HASH_MAP_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
// 默认桶的个数(动态数组默认大小)
#define DEFAULT_CAPACITY 8
// 默认负载因子
#define DEFAULT_LOAD_FACTOR 0.75

typedef char* K;    
typedef char* V;    

// 定义hashmap的链表结点
typedef struct map_node {
   
    K key;  // 键
    V value;    // 值
    struct map_node *next; // 下一个结点
} MapNode;

// 定义hashmap的桶结点
typedef struct {
   
    MapNode *head; // 桶中链表的第一个节点
    uint32_t hash_code; // 桶中键值对hash值
} Bucket;

// 定义hashmap结构体
typedef struct {
   
    Bucket **buckets;  // 存键值对的桶(动态的Bucket指针数组)
    int size;   // map中键值对个数
    int capacity; // map的容量
    double load_factor; // map的负载因子
    uint32_t hash_seed; // hash函数的种子
} HashMap;

// 创建HashMap(容量和负载因子填NULL则使用默认值)
HashMap* create_hashmap(const void* capacity_p, const void* load_factor_p);
// 销毁HashMap
void destroy_hashmap(HashMap *map);
// ---------------- 基本操作 ----------------
// 存入键值对
V put(HashMap *map, K key, V val);
// 查询键值对
V get(const HashMap *map, K key);
// 删除键值对
bool map_remove(HashMap *map, K key);
// 键key在表中是否有对应的值
bool contains(const HashMap *map, K key);
// 判断表是否为空
bool is_empty(const HashMap *map);

// ---------------- 其他操作 ----------------
// 是否需要扩容
static bool is_need_resize(const HashMap *map);
// 扩容
static void resize(HashMap *map);
// murmur_hash2 哈希函数
static uint32_t 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值