哈希表的设计与实现

简介: 哈希表的设计与实现

本文详细介绍了哈希表的数据结构,包括键值对的定义、如何通过哈希函数确定数组下标、以及如何使用链地址法解决哈希冲突。还涵盖了插入、查找和删除操作,以及哈希表的完整生命周期管理。

摘要由CSDN通过智能技术生成

哈希表实现了“键key——值value”这一映射关系的存储。每个值对应唯一的键,一个键可以对应多个值

哈希表在插入、删除、查找一个元素都只需要O(1)的时间复杂度,所以哈希表常常用来优化时间效率,在基础数据结构中,数组满足O(1)时间复杂度,所以哈希表可以考虑使用‘数组’实现。

由于每个值唯一对应一个键,需要通过键来查找特定的值,因此一个值和它唯一对应的键是同时存储的,称为‘键值对’。下图定义了一个键值对结构体:

//定义哈希表的节点结构(叫节点是因为键值对用链表存储在数组中)
typedef struct HashNode {
    char* key;
    int value;
    struct HashNode* next; // 指向下一个节点的指针,用来解决哈希冲突
} HashNode;

所以在数组中存储‘键值对’时,使用‘’来确定键值对在数组中的下标

下图为数组实现的哈希表结构:

// 哈希表结构
typedef struct {
    HashNode* array[TABLE_SIZE]; // 哈希表的桶数组
} HashTable;

将键转换成数组下标的过程:将键转换成整数(即哈希值),哈希值对数组长度求余,得到的余数为数组的下标。

键如果是英文或中文字符,则通过ASCII或Unicode转换成整数(即哈希值)。

// 哈希函数,这里简单地将键转换为整数然后取余
int hash(char* key) {
    int hashValue = 0;
    int len = strlen(key);
    for (int i = 0; i < len; i++) {
        hashValue = (hashValue << 5) + key[i];
    }
    return hashValue % TABLE_SIZE;
}

因此这样的转换方式会出现多个键具有相同的哈希值,即出现多个键值对需要存储到数组的同一个位置,很显然这会引起冲突,叫做哈希冲突

// 创建哈希表
HashTable* createHashTable() {
    HashTable* hashtable = (HashTable*)malloc(sizeof(HashTable));
    for (int i = 0; i < TABLE_SIZE; i++) {
        hashtable->array[i] = NULL;
    }
    return hashtable;
}

为了解决哈希冲突,可以把存入数组中同一位置的多个键值对用链表存储,也就是说,数组中每个位置存储的是链表。

// 插入键值对到哈希表,采用链地址法解决冲突
void insert(HashTable* hashtable, char* key, int value) {
    int index = hash(key);//哈希值
    HashNode* newNode = (HashNode*)malloc(sizeof(HashNode));//为新键值对创建新节点
    newNode->key = strdup(key);
    newNode->value = value;
    newNode->next = NULL;//初始化结点指针
    if (hashtable->array[index] == NULL) {//哈希表上所要插入的位置为空(无链表)
        hashtable->array[index] = newNode;
    } else {                              //不为空,出现冲突
        HashNode* current = hashtable->array[index];//声明当前节点指针
        while (current->next != NULL) {//遍历到该位置链表的最后一个节点
            current = current->next;//找到了最后一个节点,并将当前节点设置为最后一个节点
        }
        current->next = newNode;//将最后一个节点的next指针从NULL设置为newnode新节点
    }
}
查找:
 
// 根据键查找对应的值
int get(HashTable* hashtable, char* key) {
    int index = hash(key);
    HashNode* current = hashtable->array[index];
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            return current->value;
        }
        current = current->next;
    }
    return -1; // 表示未找到
}
删除:
 
// 从哈希表中删除指定键的键值对
void removeKey(HashTable* hashtable, char* key) {
    int index = hash(key);
    HashNode* current = hashtable->array[index];
    HashNode* prev = NULL;
    // 查找要删除的节点并记录其前驱节点
    while (current != NULL && strcmp(current->key, key) != 0) {
        prev = current;
        current = current->next;
    }
    // 如果找到了要删除的节点
    if (current != NULL) {
        // 如果要删除的节点是链表的第一个节点
        if (prev == NULL) {
            hashtable->array[index] = current->next;
        } else {
            prev->next = current->next;
        }
        // 释放要删除的节点的内存
        free(current->key);
        free(current);
    }
}
完全销毁哈希表(销毁哈希表中所有占用内存的子成员):
 
// 销毁哈希表
void destroyHashTable(HashTable* hashtable) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        HashNode* current = hashtable->array[i];
        while (current != NULL) {
            HashNode* temp = current;
            current = current->next;
            free(temp->key);//释放节点的空间
            free(temp);//释放节点的指针成员空间
        }
    }
    free(hashtable);//释放哈希表的空间
}


目录
相关文章
|
8月前
|
存储 索引
什么是哈希表?它的工作原理是什么?
在我们的日常生活中,我们经常需要存储和查找各种信息,这些信息可能是电话号码,地址,或者是商品的价格等等。这些信息的存储和查找,就像是我们在一个巨大的仓库中存放和寻找物品。这个仓库就是数据结构,而其中一个最常用的,也是最高效的数据结构就是哈希表。
119 2
|
2月前
|
存储 缓存 数据库
哈希表
【10月更文挑战第24天】哈希表是一种非常实用的数据结构,它在各种计算机应用中发挥着重要作用。通过深入了解哈希表的原理、实现和应用,我们可以更好地利用它来解决实际问题。
|
5月前
|
存储 Java
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
这篇文章通过Java代码示例展示了如何实现哈希表,包括定义结点类、链表类、数组存储多条链表,并使用简单的散列函数处理冲突,以及如何利用哈希表存储和查询学生信息。
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
|
8月前
|
存储 算法 Java
【算法系列篇】哈希表
【算法系列篇】哈希表
|
存储 算法 Serverless
|
8月前
|
算法 C++
c++算法学习笔记 (20) 哈希表
c++算法学习笔记 (20) 哈希表
|
8月前
一道题学会如何使用哈希表
一道题学会如何使用哈希表
|
8月前
|
存储 C++ 容器
C++【哈希表的模拟实现】
C++【哈希表的模拟实现】
56 0
|
存储 缓存 算法
趣味算法——探索哈希表的神秘世界
前言: 在编程世界中,数据存储和检索的效率常常是我们关注的重点。对于这个问题,哈希表提供了一个既高效又实用的解决方案。哈希表是一种通过哈希函数将键转化为数组索引,以实现快速查找的数据结构。在大多数情况下,哈希表能够在常数时间内完成查找,插入和删除操作,因此在许多应用场景中得到了广泛使用。
78 0
|
存储 数据库
第 9 章 哈希表
散列表(Hash table, 也叫哈希表) ,是根据关键码值(Key value)而直接进行访问的数据结构。
101 1

热门文章

最新文章