用C语言为班级42个人的姓名设计一个哈希表,假设姓名用汉语拼音表示。要求用线性探测再散列法处理冲突,平均查找长度的上限为2。 编写数据结构和算法来实现。 要求:将哈希函数和处理冲突方法分别封装为2个函数。
时间: 2024-03-05 22:52:23 浏览: 67
假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数采用除留余数法构造,用线性探测再散列法处理冲突。
好的,下面是一个使用线性探测再散列法解决冲突的哈希表实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABLE_SIZE 53
#define MAX_PROBE_LENGTH 2
typedef struct Node {
char *key;
struct Node *next;
} Node;
Node *table[TABLE_SIZE];
// 哈希函数,使用简单的取模法
unsigned int hash(char *key) {
unsigned int value = 0;
unsigned int i = 0;
unsigned int key_len = strlen(key);
// 遍历key中的每个字符,将其ascii码值相加
for (; i < key_len; ++i) {
value = value * 37 + key[i];
}
// 对TABLE_SIZE取模,确保哈希值在0-TABLE_SIZE-1之间
value = value % TABLE_SIZE;
return value;
}
// 处理冲突的方法,使用线性探测再散列法
unsigned int probe(unsigned int index, unsigned int i) {
return (index + i) % TABLE_SIZE;
}
// 添加键值对
void put(char *key) {
unsigned int index = hash(key);
unsigned int i = 0;
unsigned int probe_index = index;
// 线性探测,找到第一个空闲位置
while (table[probe_index] != NULL && i <= MAX_PROBE_LENGTH) {
probe_index = probe(index, ++i);
}
// 如果找到了空闲位置,则插入新节点
if (table[probe_index] == NULL) {
Node *new_node = (Node *)malloc(sizeof(Node));
new_node->key = strdup(key);
new_node->next = NULL;
table[probe_index] = new_node;
} else {
printf("Error: Hash table is full\n");
}
}
// 根据key查找节点
Node *find(char *key) {
unsigned int index = hash(key);
unsigned int i = 0;
unsigned int probe_index = index;
// 线性探测,查找key对应的节点
while (table[probe_index] != NULL && i <= MAX_PROBE_LENGTH) {
if (strcmp(table[probe_index]->key, key) == 0) {
return table[probe_index];
}
probe_index = probe(index, ++i);
}
return NULL;
}
int main() {
char *names[] = {"zhangsan", "lisi", "wangwu", "zhaoliu", "sunqi",
"liuba", "chenjiu", "zhouer", "wushisan", "zhengshi",
"fanyi", "xianghuang", "liushen", "liangqi", "fengwu",
"zhangjie", "zhaoyi", "chenjing", "yangming", "zouyun",
"zhangliu", "qianqi", "sunba", "zhoujiu", "liangliang",
"zhangqing", "liushi", "wangyue", "zhaowu", "xianzi",
"yangguang", "songshu", "liuzi", "chenming", "zhaoxing",
"jianghu", "zhangfei", "liuyi", "zhaozhao", "liyan",
"wangxiao", "fengmian", "zoubo", "sunjun", "zhaohua",
"chenkai", "yangzi", "qianlong", "gaoxia", "zhangzhang",
"liuxi", "liyue", "zhengzheng", "liujie", "yangyang"};
// 将所有姓名插入哈希表
for (int i = 0; i < 53; i++) {
put(names[i]);
}
// 查找一些姓名
Node *node = find("lisi");
if (node != NULL) {
printf("lisi is in the hash table\n");
} else {
printf("lisi is not in the hash table\n");
}
node = find("zhangsan");
if (node != NULL) {
printf("zhangsan is in the hash table\n");
} else {
printf("zhangsan is not in the hash table\n");
}
node = find("wangmazi");
if (node != NULL) {
printf("wangmazi is in the hash table\n");
} else {
printf("wangmazi is not in the hash table\n");
}
return 0;
}
```
这里使用了一个数组来存储哈希表,每个数组元素对应一个链表,链表中存储了key。在添加键值对的时候,先计算出key的哈希值,然后使用线性探测再散列法,找到第一个空闲位置并插入新节点;在查找节点的时候,也先计算出key的哈希值,然后使用线性探测再散列法,查找key对应的节点。
阅读全文