📜  使用开放寻址线性探测实现自己的哈希表(1)

📅  最后修改于: 2023-12-03 14:49:54.750000             🧑  作者: Mango

使用开放寻址线性探测实现自己的哈希表

1. 简介

哈希表是一种常用的数据结构,它可以用来存储和检索键值对。在哈希表中,键通过哈希函数转换为数组中的索引,然后将值存储在该索引对应的位置上。然而,不同的键可能会映射到同一个索引上,这就是哈希冲突。为了解决哈希冲突,我们可以使用开放寻址法来处理。

开放寻址法是一种处理哈希冲突的方法,它使用哈希函数计算出的索引,如果该位置已经被占用,则继续向后探测,直到找到一个空闲位置为止。开放寻址法有多种探测方式,其中线性探测是一种简单且常用的方式,它按照固定的步长依次探测数组中的下一个位置。

在本文中,我们将介绍如何使用开放寻址线性探测法实现自己的哈希表。

2. 实现步骤
2.1 定义哈希表结构

首先,我们需要定义一个哈希表的数据结构,用于存储键值对。这个数据结构通常包括一个存储数据的数组和一个哈希函数。

struct HashTable {
    int size;       // 哈希表的大小
    int* keys;      // 存储键的数组
    int* values;    // 存储值的数组
};
2.2 初始化哈希表

在使用哈希表之前,我们需要先进行初始化。初始化的过程包括为数组分配内存并将所有元素初始化为空。

void initHashTable(HashTable* hashTable, int size) {
    hashTable->size = size;
    hashTable->keys = (int*)malloc(size * sizeof(int));
    hashTable->values = (int*)malloc(size * sizeof(int));
    for (int i = 0; i < size; i++) {
        hashTable->keys[i] = -1;    // -1 表示空键
    }
}
2.3 哈希函数

哈希函数用于将键转换为数组的索引。我们可以选择不同的哈希函数,但为了简单起见,我们将使用取余运算作为哈希函数。

int hash(int key, int size) {
    return key % size;
}
2.4 插入键值对

当我们插入一个键值对时,先使用哈希函数计算出对应的索引,然后按照线性探测的方式找到一个空闲位置,并将键和值存储在该位置上。

void insert(HashTable* hashTable, int key, int value) {
    int index = hash(key, hashTable->size);
    while (hashTable->keys[index] != -1) {
        index = (index + 1) % hashTable->size;    // 线性探测
    }
    hashTable->keys[index] = key;
    hashTable->values[index] = value;
}
2.5 查询值

查询值的操作与插入类似,也需要使用哈希函数计算出索引,然后按照线性探测的方式找到对应的键,并返回对应的值。

int get(HashTable* hashTable, int key) {
    int index = hash(key, hashTable->size);
    while (hashTable->keys[index] != key) {
        index = (index + 1) % hashTable->size;    // 线性探测
    }
    return hashTable->values[index];
}
2.6 删除键值对

删除键值对的操作也与插入类似,需要使用哈希函数计算出索引,然后按照线性探测的方式找到对应的键,并将其标记为已删除。

void remove(HashTable* hashTable, int key) {
    int index = hash(key, hashTable->size);
    while (hashTable->keys[index] != key) {
        index = (index + 1) % hashTable->size;    // 线性探测
    }
    hashTable->keys[index] = -1;    // 标记为已删除
}
3. 使用示例

下面是一个使用开放寻址线性探测实现的哈希表的示例代码。

int main() {
    int size = 10;
    HashTable hashTable;
    initHashTable(&hashTable, size);
    
    insert(&hashTable, 1, 10);
    insert(&hashTable, 2, 20);
    insert(&hashTable, 11, 30);
    
    int value1 = get(&hashTable, 1);
    int value2 = get(&hashTable, 2);
    int value3 = get(&hashTable, 11);
    
    printf("value1: %d\n", value1);
    printf("value2: %d\n", value2);
    printf("value3: %d\n", value3);
    
    remove(&hashTable, 2);
    
    return 0;
}
4. 总结

开放寻址线性探测法是一种处理哈希冲突的简单有效的方法。它使用线性探测的方式来找到空闲位置,并处理哈希表中的插入、查询和删除操作。通过了解和实践这种方法,我们可以更好地理解哈希表的原理和实现,并在需要时根据实际情况选择合适的处理哈希冲突的方法。