为班级同学(10人以上)的姓名设计一个哈希表,假设姓名用汉语拼音表示。要求用除留余数法构造哈希函数,再用线性探测再散列法处理冲突,平均查找长度的上限为2
时间: 2025-02-13 18:24:21 浏览: 35
为了为班级同学的姓名设计一个哈希表,我们首先需要确定几个关键步骤:
1. **哈希函数的选择**:由于我们要使用除留余数法(也称为取模法),我们需要一个合适的散列基数(即用于计算余数的数字)。一个常见的选择是数组的大小,通常选择比班级人数大且易于计算的质数,例如101(因为101是素数且易于与名字长度配合)。哈希函数的基本形式可以是 `hash(name) = (name.length() % modulus)`。
2. **线性探测再散列**:如果两个或更多的名字被哈希到同一个位置(冲突),我们将使用线性探测再散列来寻找下一个空的位置。这涉及到从当前索引开始,依次检查每个位置直到找到一个空闲的。如果所有的位置都满了,就循环回到第一个位置,直到找到合适的位置。
以下是一个简单的示例,展示了如何创建这样一个哈希表结构和操作:
```c
#include <stdio.h>
#include <string.h>
// 哈希表的大小
#define TABLE_SIZE 101
typedef struct {
char *name;
int count; // 记录该键出现的次数,这里默认为1,用于线性探测
} Student;
Student table[TABLE_SIZE] = {0}; // 初始化所有元素为未分配
// 哈希函数
int hash_function(const char *name) {
return strlen(name) % TABLE_SIZE;
}
// 线性探测再散列
int linear_probe(int index, const char *name) {
while (table[index].name != NULL && strcmp(table[index].name, name) != 0) {
index = (index + 1) % TABLE_SIZE;
}
return index;
}
// 插入学生名
void insert_name(char *name) {
int index = hash_function(name);
if (table[index].name == NULL) {
table[index].name = strdup(name); // 复制姓名并保存
table[index].count = 1; // 新添加一个记录
} else {
index = linear_probe(index, name);
table[index].count++; // 如果已有,计数加一
}
}
// 查找学生名
char* find_name(char *name) {
int index = hash_function(name);
while (table[index].name != NULL && strcmp(table[index].name, name) != 0) {
if (table[(index+1)%TABLE_SIZE].name == NULL) break; // 找到间隔中的空位
index = (index + 1) % TABLE_SIZE;
}
return table[index].name;
}
// 删除学生名(如果存在)
void delete_name(char *name) {
int index = hash_function(name);
if (table[index].name != NULL && strcmp(table[index].name, name) == 0) {
free(table[index].name);
table[index].name = NULL;
table[index].count--;
}
}
int main() {
// 添加/查找/删除同学姓名
insert_name("张三");
printf(find_name("张三") ? "找到了" : "没找到"); // 输出:找到了
delete_name("张三");
printf(find_name("张三") ? "找到了" : "没找到"); // 输出:没找到
return 0;
}
```
阅读全文
相关推荐













