哈希表(Hash Table)是一种用于存储键值对的数据结构,能够在常数时间内进行插入、删除和查找操作。哈希表的基本思想是通过一个哈希函数将键映射到表中的一个位置,避免了线性查找的高时间复杂度。
#include <stdio.h>
#include <stdlib.h>
#define SIZE 9
typedef struct Element {
int key;
}*E;
typedef struct HashTable {
E *table;
}*HashTable;
void initHashTable(HashTable hashTable) {
hashTable->table = malloc(sizeof(E) * SIZE); // 分配存储空间
for (int i = 0; i < SIZE; ++i) {
hashTable->table[i] = NULL; // 初始化哈希表,每个位置指针为NULL
}
}
int hash(int key) {
return key % SIZE; // 简单的取模哈希函数
}
// void insert(HashTable hashTable, E element) {
// int hashcode = hash(element->key);
// hashTable->table[hashcode] = element; // 如果碰到冲突,将新元素覆盖旧元素
// }
// _Bool find(HashTable hashTable, int key) {
// int hashcode = hash(key);
// if (hashTable->table[hashcode] == NULL) return 0; // 查找失败
// return hashTable->table[hashcode]->key == key; // 如果相等,查找成功
// }
void insert(HashTable hashTable, E element) { // 使用开放定址法
int hashcode = hash(element->key), count = 0;
while (hashTable->table[hashcode]) { // 如果当前位置已有元素
hashcode = hash(element->key + ++count); // 使用线性探测法查找下一个位置
}
hashTable->table[hashcode] = element; // 插入元素
}
_Bool find(HashTable hashTable, int key) {
int hashcode = hash(key), count = 0;
const int start = hashcode; // 记录起始位置,用于判断是否循环回来
do {
if (hashTable->table[hashcode]->key == key) return 1; // 查找成功
hashcode = hash(++count); // 使用线性探测法查找
} while (start != hashcode && hashTable->table[hashcode]); // 如果回到起始位置或当前位置为空,查找结束
return 0; // 查找失败
}
E create(int key) {
E element = malloc(sizeof(struct Element)); // 创建一个新的元素
element->key = key; // 设置元素的key
return element;
}
int main() {
struct HashTable table;
initHashTable(&table); // 初始化哈希表
// 插入元素的代码已经被注释掉,以下是我的思考过程:
// insert(&table, create(10)); // 插入key为10的元素
// insert(&table, create(7)); // 插入key为7的元素
// insert(&table, create(13)); // 插入key为13的元素
// insert(&table, create(29)); // 插入key为29的元素
// printf("%d\n", find(&table, 10)); // 查找key为10的元素,预期返回1
for (int i = 0; i < SIZE; ++i) {
insert(&table, create(i * 10)); // 插入一组元素,每个元素的key为i*10
}
for (int i = 0; i < SIZE; ++i) {
if (table.table[i]) {
printf("%d ", table.table[i]->key); // 打印哈希表中的元素
} else {
printf("NULL "); // 如果该位置为空,则打印NULL
}
}
}