哈希表的实现(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

相关推荐
whltaoin4 分钟前
贪心算法:部分背包问题深度解析
算法·贪心算法
龙虾在剥我的壳7 分钟前
OpenCV——图像融合
c++·opencv·计算机视觉
不眠之夜13 分钟前
龟兔赛跑:快慢指针法详解(Floyd's Tortoise and Hare Algorithm)
算法
零零壹1117 分钟前
Apipost自定义函数深度实战:灵活处理参数值秘籍
算法·面试·github
搞程序的心海20 分钟前
当机器学习遇见购物车分析:FP-Growth算法全解析
算法
Ludicrouers24 分钟前
【Leetcode-Hot100】字母异位词分组
算法·leetcode·职场和发展
末央&1 小时前
【C++】list底层封装和实现
c++·windows·list
Zhichao_971 小时前
【UE5 C++课程系列笔记】35——HTTP基础——HTTP客户端异步请求API接口并解析响应的JSON
c++·ue5
aw3441 小时前
tiny_dnn_test250101
人工智能·算法·dnn
风铃儿~1 小时前
Redis过期key处理、内存淘汰策略与缓存一致性策略实践方案
java·数据结构·redis·微服务