C语言 手撕一个HashMap

💡 原文中文,约2200字,阅读约需6分钟。
📝

内容提要

该文章介绍了使用链地址法处理哈希冲突的HashMap实现。通过定义哈希表和哈希桶结构体,创建指定大小的哈希表,实现哈希函数、put操作和get操作,以及释放内存的函数。文章还提供了一个main方法测试的示例。

🔎

延伸解读

链地址法的实现要点

文章采用链地址法处理哈希冲突,每个哈希桶位置存储一个链表。put操作在冲突时将新节点追加到链表末尾,get操作则遍历链表查找匹配的键。这种实现简单直接,但插入时需遍历整个链表,当链表较长时效率会下降。

哈希函数与冲突分布

哈希函数通过累加键的字符值并对表大小取模来计算索引。这种简单哈希函数容易产生冲突,尤其当键的字符和相近时。文章示例中表大小固定为10,实际使用中需根据数据量调整大小以减少冲突。

内存管理注意事项

createHashMap使用calloc初始化桶数组,put中使用strdup复制键字符串,freeHashMap则遍历所有桶释放节点、键字符串及桶数组本身。这种手动内存管理要求调用者确保正确释放,避免内存泄漏。

功能局限与扩展方向

当前实现仅支持字符串键和整数值,且get未找到时返回-1,可能无法区分存储的值就是-1的情况。此外,没有删除操作和动态扩容机制,这些是实际应用中可能需要补充的功能。

❓

Q&A

如何使用链地址法实现HashMap?

使用链地址法实现HashMap时,每个哈希桶存储一个链表,哈希冲突时将新的键值对添加到链表末尾。

HashMap的put操作是如何实现的?

put操作通过计算键的哈希值找到对应的桶,如果桶为空则直接插入,否则将新节点添加到链表末尾。

如何从HashMap中获取值?

使用get操作,通过计算键的哈希值找到对应的桶,然后遍历链表查找匹配的键,返回其值。

如何创建一个指定大小的HashMap?

使用createHashMap函数,传入所需大小,分配内存并初始化哈希表和哈希桶。

HashMap的内存释放是如何处理的?

使用freeHashMap函数,遍历每个桶的链表,释放每个节点的内存,最后释放哈希表本身的内存。

在main方法中如何测试HashMap的功能?

在main方法中创建HashMap实例,使用put插入键值对,然后使用get获取并打印值,最后释放内存。

🏷️

标签

➡️

继续阅读