目录
关键词:哈希表、哈希算法
这篇文章简单介绍一下哈希表,并利用其原理对哈希表进行简单的实现。部分内容参考HELLO算法,欢迎大家学习HELLO算法!
哈希表是一种非常高效的数据结构,用于存储键值对,并且能够提供快速的查找操作。它通过将键映射到表中的一个位置来实现快速的查找,这个映射函数通常称为哈希函数。哈希表的优势在于它能够以接近 O(1) 的时间复杂度进行查找、插入和删除操作,这使得它在处理大量数据时非常高效。
在写代码之前,我们应该想一下用这个哈希能来做什么?我想的是肯定能用来存储数据,既然存进去了肯定能够读取出来。这是大家都能想到的吧,所以我们就这个问题来写代码。
特别提醒:大家不要把这个东西想得太复杂,你就想成是某个人需要达到某个需求,新找到一个途径而已,所以呢,这个就可以很粗略的看成数组的应用,希望大家能明白我的意思。
第一步: 创建哈希表
Pair结构体大家应该能看明白,ArrayHashMap结构体就是包含了MAX_SIZE个Pair结构体,在构造函数里面为hmap动态开辟空间,并且逐一遍历为NULL,这个过程就是初始化过程(创建哈希表)。
#define MAX_SIZE 100
/* 键值对 int->string */
typedef struct {
int key;
char *val;
} Pair;
/* 基于数组实现的哈希表 */
typedef struct {
Pair *buckets[MAX_SIZE];
} ArrayHashMap;
/* 构造函数 */
ArrayHashMap *newArrayHashMap() {
ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));
for(int i=0;i<MAX_SIZE;i++)
hmap->buckets[i] = NULL;
return hmap;
}
创建了哈希表之后肯定就是添加键值对对吗?
第二步:添加键值对
大家大致看一下代码,在put函数里的动态开辟空间这个很常见了,应该都会就不多说,这里用了strlen和strcpy两个库函数,大家记得加库。
最主要的是hashFunc这个函数,这个函数的作用就是提供索引,如果把上一步理解清楚了,这一步就自然而然能够想到找这个索引的目的就是为了找到存放在这个数组的位置,这也是哈希表查找的最大优势。简简单单的一个取模运算就可以找到索引,从而存储数据。
/* 哈希函数 */
int hashFunc(const int key) {
return key % MAX_SIZE; // 使用取模运算作为哈希函数
}
/* 添加操作 */
void put(ArrayHashMap *hmap, const int key, const char *val) {
Pair *Pair = malloc(sizeof(Pair));
Pair->key = key;
Pair->val = malloc(sizeof(strlen(val) + 1));
strcpy(Pair->val,val);
int index = hashFunc(key);
hmap->buckets[index] = Pair;
}
示例:
// 创建哈希表
ArrayHashMap *hmap = newArrayHashMap();
// 添加学生信息
put(hmap, 2021001, "张三");
put(hmap, 2021002, "李四");
put(hmap, 2021003, "王五");
第三步:打印哈希表(输出数组的意思)
/* 打印哈希表 */
void print(ArrayHashMap *hmap) {
printf("哈希表内容:\n");
for (int i = 0; i < MAX_SIZE; i++) {
if (hmap->buckets[i] != NULL) {
printf("%d -> %s\n", hmap->buckets[i]->key, hmap->buckets[i]->val);
}
}
}
第四步:查找特定信息(利用哈希函数)
这一步就是查找哈希表内容的部分,很简单的。
/* 根据键获取值 */
char* get(ArrayHashMap *hmap, const int key) {
int index = hashFunc(key); // 使用取模运算作为哈希函数
if (hmap->buckets[index] != NULL && hmap->buckets[index]->key == key) {
return hmap->buckets[index]->val;
}
return NULL;
}
第五步:释放内存空间(这个不用太在意)
这个 delArrayHashMap
函数是一个析构函数,用于释放哈希表及其包含的内存。它的作用是:
-
遍历哈希表中的每个桶(bucket),如果桶中存在键值对(即不为 NULL),则释放对应的值(
val
)所占用的内存空间,然后释放键值对结构体(Pair
)所占用的内存空间。 -
最后,释放哈希表结构体本身所占用的内存空间。
通过这个析构函数,可以确保在不再需要哈希表时,释放所有相关的内存,以避免内存泄漏问题。
/* 析构函数 */
void delArrayHashMap(ArrayHashMap *hmap) {
for(int i=0;i<MAX_SIZE;i++) {
if(hmap->buckets[i] != NULL) {
free(hmap->buckets[i]->val);
free(hmap->buckets[i]);
}
}
free(hmap);
}
下面是完整代码示例,仅供参考:哈希表示例代码https://download.youkuaiyun.com/download/m0_72105319/89288868
哈希部分持续更新…