C++学习笔记(三十四)——hashtable(哈希表)

一、HashTable(哈希表)

(1)HashTable与其核心思想

哈希表(Hash Table)是一种基于哈希函数的键值映射数据结构,它能在O(1) 的均摊时间复杂度内完成查找、插入和删除操作

核心思想:

  1. 通过哈希函数(Hash Function) 计算键的哈希值,映射到一个索引位置。
  2. 若索引位置冲突(两个键映射到相同索引),使用冲突解决策略(如链地址法或开放寻址法) 处理。
  3. 负载因子(Load Factor) 影响哈希表性能,通常超过阈值时会进行动态扩容

其中,负载因子是指哈希表中已存储元素数量与总容量的比值,用于衡量哈希表的填充程度

(2)HashTable的实现

STL 容器底层实现是否有序允许重复键/值
unordered_map哈希表
unordered_multimap哈希表
unordered_set哈希表
unordered_multiset哈希表

使用建议:

  • 需要 O(1) 查找?用 unordered_map(哈希表)。
  • 需要唯一键值?用 unordered_set(哈希集合)。
  • 需要允许重复键?用 unordered_multimap
  • 需要允许重复值?用 unordered_multiset

(3)红黑树(map) vs 哈希表(unordered_map

红黑树 (map)哈希表 (unordered_map)
底层结构红黑树哈希表
插入/删除/查找O(log n)O(1)(均摊)
是否有序是(按键排序)否(无序存储)
适用场景需要排序、范围查询仅关心查找速度

二、unordered_map(哈希表的键值映射)

(1)常用函数

函数作用
insert({Key, Value})插入键值对
find(Key)查找键,返回迭代器(不存在则 end()
erase(Key)删除键
count(Key)返回键的个数(对于 unordered_map 只能是 01
size()返回元素个数
clear()清空哈希表

(2)基本使用

#include <iostream>
using namespace std;
#include <unordered_map>
#include <string>

int main() {
    unordered_map<string, int> hash_table;

    // 插入键值对
    hash_table["Apple"] = 10;
    hash_table["Banana"] = 20;
    hash_table["Cherry"] = 30;

    // 查找键值对
    if (hash_table.find("Banana") != hash_table.end())
    {
        cout << "Banana 的值是: " << hash_table["Banana"] << endl;
    }

    // 遍历哈希表(无序)
    cout << "哈希表内容:" << endl;
    for (const auto& pair : hash_table)
    {
        cout << pair.first << " -> " << pair.second << endl;
    }

    system("pause");
    return 0;
}

注意:

  • unordered_map中采用无序存储
  • 查找 find()的复杂度为O(1)
  • [] 访问键时,若键不存在,会创建默认值

三、unordered_set(哈希表的无序集合)

(1)常用函数

函数作用
insert(Value)插入元素
find(Value)查找元素,返回迭代器
erase(Value)删除元素
count(Value)返回元素个数(只能是 01
size()返回集合大小
clear()清空集合

(2)基本使用

#include <iostream>
using namespace std;
#include <unordered_set>

int main() {
    unordered_set<int> hash_set = {10, 20, 30, 40};

    // 插入元素
    hash_set.insert(50);
    hash_set.insert(30); // 30 已存在,不会重复插入

    // 查找元素
    if (hash_set.find(20) != hash_set.end())
    {
        cout << "20 存在于哈希集合中" << endl;
    }

    // 遍历哈希集合(无序)
    cout << "哈希集合中的元素: ";
    for (int num : hash_set)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • unordered_set 基于哈希表实现集合元素唯一,自动去重)。
  • 采用无序存储,适用于快速去重、判重、查找
  • 查找 find()的复杂度为O(1)

四、unordered_multimapunordered_multiset(允许重复键/值的哈希表)

  • unordered_multimap——允许 重复键 的无序哈希表。
  • unordered_multiset——允许 重复值 的无序哈希集合。

(1)unordered_multimap的使用

#include <iostream>
using namespace std;
#include <unordered_map>
#include <string>

int main() {
    unordered_multimap<int, string> multi_hash_map;

    // 插入重复键
    multi_hash_map.insert({ 1, "Apple" });
    multi_hash_map.insert({ 2, "Banana" });
    multi_hash_map.insert({ 1, "Avocado" }); // 允许重复键

    // 遍历哈希表
    cout << "unordered_multimap 内容:" << endl;
    for (const auto& pair : multi_hash_map)
    {
        cout << pair.first << " -> " << pair.second << endl;
    }

    system("pause");
    return 0;
}

注意:

  • unordered_multimap允许多个相同键,适用于数据库索引等。

(2)unordered_multiset的使用

#include <iostream>
using namespace std;
#include <unordered_set>

int main() {
    unordered_multiset<int> hash_multiset = { 10, 20, 30 };

    // 插入元素
    hash_multiset.insert(20); // 允许重复值
    hash_multiset.insert(30); // 允许重复值
    hash_multiset.insert(40);


    // 遍历哈希集合(无序)
    cout << "哈希集合中的元素: ";
    for (int num : hash_multiset)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奕天者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值