代码
hash.c
/*
* @Author: ZPY
* @TODO: 创建一个哈希表,实现其功能
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOAD_FACTOR 0.7 // 装载因子
typedef struct hash
{
char **str; // 字符串数组
int capacity;
int size;
} Hash;
// 哈希表操作
void init(Hash *hash);
void insert(Hash *hash, char *str);
void delete(Hash *hash, char *str);
void display(Hash *hash);
void incr(Hash *hash);
void destory(Hash *hash);
int get_num(char *str);
int size(Hash *hash);
char *get_str();
char buf[1024] = {'\0'}; // 全局字符数组
int main(int argc, char const *argv[])
{
int choice;
Hash *hash = malloc(sizeof(Hash));
printf("欢迎使用哈希表!\n");
init(hash); // 初始化哈希表
while (1)
{
printf("============字符串哈希表 1.0============\n");
printf("==============1. 存入字符串=============\n");
printf("==============2. 删除字符串=============\n");
printf("==============3. 查看字符串=============\n");
printf("==============4. 退出本系统=============\n");
scanf("%d", &choice);
getchar(); // 吸收换行符
char *str;
switch (choice)
{
case 1:
str = get_str();
insert(hash, str);
break;
case 2:
str = get_str();
delete (hash, str);
break;
case 3:
display(hash);
break;
case 4:
destory(hash);
return 0;
}
}
return 0;
}
void init(Hash *hash)
{
hash->capacity = 5;
hash->size = 0;
hash->str = malloc(sizeof(char *) * hash->capacity);
for (int i = 0; i < hash->capacity; i++)
{
hash->str[i] = NULL;
}
}
void insert(Hash *hash, char *str)
{
if (hash->size > hash->capacity * LOAD_FACTOR) // 如果当前哈希表存储内容大于装载比例,就扩容
{
incr(hash);
}
int index = get_num(str) % hash->capacity;
while (hash->str[index])
{
index++;
index = index % hash->capacity; // 如果当前位置已经有值了,就往后找空位
}
hash->str[index] = strdup(str);
hash->size++;
}
void delete(Hash *hash, char *str)
{
int index = get_num(str) % hash->capacity;
int i;
for (i = 0; i < hash->capacity; i++)
{
if (hash->str[index] && strcmp(hash->str[index], str) == 0) // 先判断字符串是不空再比较
{
free(hash->str[index]); // 先释放字符串内存空间
hash->str[index] = NULL;
break;
}
else
{
index++;
index %= hash->capacity;
}
}
if (i == hash->capacity) // 如果没找到这个字符串
{
printf("哈希表内未保存此字符串。\n");
return;
}
printf("删除成功!\n");
hash->size--;
}
void display(Hash *hash)
{
for (int i = 0; i < hash->capacity; i++)
{
if (hash->str[i])
{
printf("hash[%d] = %s\n", i, hash->str[i]);
}
else
{
printf("hash[%d] = NULL\n", i);
}
}
printf("hash->size = %d\n", size(hash));
}
void incr(Hash *hash) // 每次扩容之后要重新散列字符串
{
// 记录原来的容量和内容
int old_capacity = hash->capacity;
char **old_str = hash->str;
hash->capacity = hash->capacity << 1; // 扩容为原来的两倍
hash->str = malloc(hash->capacity * sizeof(char *));// 在新的空间上分配
for (int i = 0; i < hash->capacity; i++)
{
hash->str[i] = NULL;
}
hash->size = 0; // 哈希表长度归零
for (int i = 0; i < old_capacity; i++)
{
if (old_str[i])
{
insert(hash, old_str[i]); // 将原来的内容重新散列
free(old_str[i]); // 释放原来的内容
}
}
free(old_str);
}
void destory(Hash *hash)
{
for (int i = 0; i < hash->capacity; i++)
{
free(hash->str[i]); // 依次释放字符串内容
}
free(hash->str);
free(hash); // 释放哈希表
}
int get_num(char *str)
{
int res = 0;
int len = strlen(str);
while (len--)
{
res += str[len];
}
return res;
}
char *get_str()
{
printf("请输入字符串:");
fgets(buf, sizeof(buf), stdin);
buf[strcspn(buf, "\n")] = '\0'; // 去除末尾换行符
return buf;
}
int size(Hash *hash)
{
return hash->size;
}
编译
gcc hash.c -o hash