用C语言代码实现哈希表的构造和查找算法,要求:用除留余数法构造哈希函数,分别用一次探测再散列、二次探测再散列解决冲突。
时间: 2024-03-20 10:39:58 浏览: 141
好的,以下是哈希表的构造和查找算法的C语言代码实现,包括除留余数法构造哈希函数和一次探测再散列、二次探测再散列解决冲突:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABLE_SIZE 10
// 哈希表节点结构体
typedef struct HashNode {
char *key; // 键
int value; // 值
} HashNode;
// 哈希表结构体
typedef struct HashTable {
HashNode **nodes; // 指向节点指针的指针,即二级指针
int size; // 哈希表大小
} HashTable;
// 创建哈希表
HashTable *createHashTable() {
HashTable *hashTable = malloc(sizeof(HashTable));
hashTable->nodes = malloc(sizeof(HashNode *) * TABLE_SIZE);
memset(hashTable->nodes, 0, sizeof(HashNode *) * TABLE_SIZE);
hashTable->size = TABLE_SIZE;
return hashTable;
}
// 除留余数法构造哈希函数
int hash(char *key) {
int hashVal = 0;
while (*key != '\0') {
hashVal = (hashVal * 31 + *key) % TABLE_SIZE;
key++;
}
return hashVal;
}
// 插入键值对
void insert(HashTable *hashTable, char *key, int value) {
int index = hash(key); // 计算哈希值
HashNode *node = malloc(sizeof(HashNode));
node->key = key;
node->value = value;
if (hashTable->nodes[index] == NULL) {
// 插入到空节点
hashTable->nodes[index] = node;
} else {
// 冲突,使用一次探测再散列解决
int i;
for (i = index + 1; i != index; i = (i + 1) % TABLE_SIZE) {
if (hashTable->nodes[i] == NULL) {
hashTable->nodes[i] = node;
return;
}
}
// 一次探测再散列失败,使用二次探测再散列解决
int step = 1;
for (i = index + step * step; i != index; i = (i + (++step) * step) % TABLE_SIZE) {
if (hashTable->nodes[i] == NULL) {
hashTable->nodes[i] = node;
return;
}
}
}
}
// 查找键对应的值
int lookup(HashTable *hashTable, char *key) {
int index = hash(key); // 计算哈希值
if (hashTable->nodes[index] == NULL) {
// 未找到节点
return -1;
} else if (strcmp(hashTable->nodes[index]->key, key) == 0) {
// 找到节点
return hashTable->nodes[index]->value;
} else {
// 冲突,使用一次探测再散列解决
int i;
for (i = index + 1; i != index; i = (i + 1) % TABLE_SIZE) {
if (hashTable->nodes[i] == NULL) {
// 未找到节点
return -1;
} else if (strcmp(hashTable->nodes[i]->key, key) == 0) {
// 找到节点
return hashTable->nodes[i]->value;
}
}
// 一次探测再散列失败,使用二次探测再散列解决
int step = 1;
for (i = index + step * step; i != index; i = (i + (++step) * step) % TABLE_SIZE) {
if (hashTable->nodes[i] == NULL) {
// 未找到节点
return -1;
} else if (strcmp(hashTable->nodes[i]->key, key) == 0) {
// 找到节点
return hashTable->nodes[i]->value;
}
}
}
}
int main() {
HashTable *hashTable = createHashTable();
insert(hashTable, "apple", 1);
insert(hashTable, "banana", 2);
insert(hashTable, "cat", 3);
insert(hashTable, "dog", 4);
insert(hashTable, "elephant", 5);
printf("banana: %d\n", lookup(hashTable, "banana"));
printf("cat: %d\n", lookup(hashTable, "cat"));
printf("elephant: %d\n", lookup(hashTable, "elephant"));
printf("fox: %d\n", lookup(hashTable, "fox"));
return 0;
}
```
上述代码中,`HashTable` 结构体包含一个指向节点指针的指针 `nodes` 和哈希表大小 `size`,节点结构体 `HashNode` 包含键 `key` 和值 `value`。首先使用 `createHashTable` 函数创建哈希表,然后使用 `hash` 函数计算键的哈希值,接着使用 `insert` 函数将键值对插入哈希表中,如果出现冲突,则使用一次探测再散列或二次探测再散列解决。最后使用 `lookup` 函数查找键对应的值,如果未找到节点,则返回 `-1`。
在 `main` 函数中,首先创建哈希表,然后插入若干个键值对,接着使用 `lookup` 函数查找键对应的值,并输出结果。
需要注意的是,上述代码中的哈希表大小为 10,即 `TABLE_SIZE` 宏定义的值,可以根据实际情况进行调整。
阅读全文