哈希表的实现(C++ 和 C 语言)

哈希表简介

哈希表是一种通过哈希函数将键映射到数组索引的数据结构,能够实现高效的数据查找、插入和删除。适用于需要快速访问的场景。

C语言实现

代码示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TABLE_SIZE 10 // 定义哈希表的大小

// 哈希表节点
typedef struct Node {
    char *key;
    int value;
    struct Node *next; // 链表的下一个节点
} Node;

// 哈希表结构体
typedef struct HashTable {
    Node **table; // 指向节点的指针数组
} HashTable;

// 哈希函数
unsigned int hash(char *key) {
    unsigned int hash = 0;
    while (*key) {
        hash = (hash << 5) + *key++; // 计算哈希值
    }
    return hash % TABLE_SIZE; // 返回索引
}

// 创建哈希表
HashTable* create_table() {
    HashTable *ht = malloc(sizeof(HashTable));
    ht->table = malloc(sizeof(Node*) * TABLE_SIZE);
    for (int i = 0; i < TABLE_SIZE; i++) {
        ht->table[i] = NULL; // 初始化为空
    }
    return ht;
}

// 插入键值对
void insert(HashTable *ht, char *key, int value) {
    unsigned int index = hash(key);
    Node *new_node = malloc(sizeof(Node));
    new_node->key = strdup(key); // 复制键
    new_node->value = value;
    new_node->next = ht->table[index]; // 插入到链表头部
    ht->table[index] = new_node;
}

// 查找值
int search(HashTable *ht, char *key) {
    unsigned int index = hash(key);
    Node *current = ht->table[index];
    while (current) {
        if (strcmp(current->key, key) == 0) {
            return current->value; // 找到返回值
        }
        current = current->next; // 继续查找
    }
    return -1; // 找不到返回 -1
}

// 释放哈希表内存
void free_table(HashTable *ht) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        Node *current = ht->table[i];
        while (current) {
            Node *temp = current;
            current = current->next;
            free(temp->key); // 释放键
            free(temp);
        }
    }
    free(ht->table); // 释放表
    free(ht); // 释放哈希表结构体
}

int main() {
    HashTable *ht = create_table();
    insert(ht, "apple", 1);
    insert(ht, "banana", 2);
    printf("Value for key 'apple': %d\n", search(ht, "apple"));
    printf("Value for key 'banana': %d\n", search(ht, "banana"));
    
    free_table(ht); // 释放内存
    return 0;
}

C++语言实现

代码示例

#include <iostream>
#include <string>
#include <list>
#include <vector>

class HashTable {
private:
    static const int TABLE_SIZE = 10; // 定义哈希表的大小
    std::vector<std::list<std::pair<std::string, int>>> table; // 使用链表处理碰撞

    // 哈希函数
    int hash(const std::string &key) {
        int hash = 0;
        for (char ch : key) {
            hash = (hash * 31 + ch) % TABLE_SIZE; // 计算哈希值
        }
        return hash;
    }

public:
    HashTable() : table(TABLE_SIZE) {} // 初始化哈希表

    // 插入键值对
    void insert(const std::string &key, int value) {
        int index = hash(key);
        table[index].emplace_back(key, value); // 使用 emplace_back 插入
    }

    // 查找值
    int search(const std::string &key) {
        int index = hash(key);
        for (const auto &pair : table[index]) {
            if (pair.first == key) {
                return pair.second; // 找到返回值
            }
        }
        return -1; // 找不到返回 -1
    }
};

int main() {
    HashTable ht;
    ht.insert("apple", 1);
    ht.insert("banana", 2);
    std::cout << "Value for key 'apple': " << ht.search("apple") << std::endl;
    std::cout << "Value for key 'banana': " << ht.search("banana") << std::endl;
    return 0;
}

哈希表优缺点

优点

  1. 快速查找:在平均情况下,查找、插入和删除的时间复杂度为 O(1)O(1)O(1)。

  2. 动态扩展:可以根据负载因子扩展哈希表大小,以适应更多数据。

  3. 灵活性:可以存储不同类型的数据。

缺点

  1. 碰撞问题:哈希函数可能会导致多个键映射到同一索引,影响性能。

  2. 内存占用:如果哈希表过大或负载因子过低,可能造成内存浪费。

  3. 复杂性:实现和维护较为复杂,特别是在处理碰撞和扩展时。

注意

⚠️这是简单叙述想深入理解点击链接🔗z

相关推荐
yuyanjingtao8 分钟前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Jasmine_llq13 分钟前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹24 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
charlie11451419136 分钟前
C++ STL CookBook
开发语言·c++·stl·c++20
Lenyiin43 分钟前
01.02、判定是否互为字符重排
算法·leetcode
小林熬夜学编程1 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
倔强的石头1061 小时前
【C++指南】类和对象(九):内部类
开发语言·c++
鸽鸽程序猿1 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd1 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表