哈希表:O(1)查找的终极指南

一、哈希表核心思想

哈希表又称散列表,核心逻辑:通过哈希函数,把关键字直接映射到数组下标 实现近乎 O(1) 时间复杂度的查找、插入、删除。

普通数组:按下标找值哈希表:按值直接找存储位置

二、哈希函数作用

公式:存储下标 = hash(关键字)设计原则:

  1. 计算速度快
  2. 映射分布均匀,减少扎堆
  3. 尽量减少重复映射结果

常用简单哈希:取模运算

复制代码
hash(key) = key % 数组长度

三、哈希冲突

不同关键字,经过哈希函数算出同一个下标,即为哈希冲突。例如:长度为 10 数组,11 和 21 取模结果一致。

无法彻底避免,只能高效解决

四、两大主流冲突解决方式

1. 开放定址法

冲突后向后寻找空闲位置存放

  • 线性探测:往后逐个遍历空位
  • 二次探测:跳跃式寻找缺点:容易产生数据聚集,查找效率下降

2. 链地址法(拉链法)【工程最常用】

数组每个位置挂一条链表

  • 映射下标相同的元素,全部挂载在同一条链表上
  • 查询时先定位数组下标,再遍历短链表查找
  • C++ unordered_map/unordered_set 底层默认采用拉链法

五、负载因子

负载因子 = 元素个数 / 哈希表容量负载因子越大,冲突越多、效率越低C++ 无序容器默认达到阈值自动扩容重新哈希

六、C++ 哈希容器分类

  1. unordered_set:无序集合,元素唯一,底层哈希表
  2. unordered_map:无序键值对,key 唯一,刷题最常用
  3. set/map:有序,底层红黑树,O (logn)

选型口诀

  • 只需要快速查找、去重、存取无序 → 用哈希表 unordered
  • 需要自动排序、有序遍历 → 用红黑树 map/set

七、unordered_map 全套刷题用法

头文件

复制代码
#include <unordered_map>
#include <iostream>
#include <string>
using namespace std;

基础增删改查

复制代码
int main()
{
    unordered_map<string,int> mp;

    // 插入
    mp["张三"] = 20;
    mp["李四"] = 22;
    mp.insert({"王五",19});

    // 取值
    cout << mp["张三"] << endl;

    // 修改
    mp["张三"] = 25;

    // 查找
    if(mp.find("李四") != mp.end())
    {
        cout << "存在该键" << endl;
    }

    // 删除
    mp.erase("王五");

    // 遍历
    for(auto& p : mp)
    {
        cout << p.first << " " << p.second << endl;
    }

    // 判空、大小
    mp.empty();
    mp.size();
    return 0;
}

八、经典刷题例题:两数之和

LeetCode 1 原题,哈希表经典秒杀模板

复制代码
#include <vector>
#include <unordered_map>
using namespace std;

vector<int> twoSum(vector<int>& nums, int target)
{
    unordered_map<int,int> hash;
    for(int i = 0; i < nums.size(); i++)
    {
        int need = target - nums[i];
        if(hash.find(need) != hash.end())
        {
            return {hash[need],i};
        }
        hash[nums[i]] = i;
    }
    return {};
}

思路:边遍历边存值,寻找互补数字,一次遍历完成。

九、哈希表优缺点

优点

  1. 查找插入删除平均 O (1),速度极快
  2. 适合海量数据快速匹配、统计频次

缺点

  1. 无序存储,无法有序遍历
  2. 存在哈希冲突,极端情况退化成链表 O (n)
  3. 内存占用相对更高

十、面试高频考点

  1. 哈希表为什么查询快?哈希映射直接定位下标
  2. 哈希冲突怎么解决?拉链法、开放定址法
  3. unordered_map 和 map 底层区别与效率差异
  4. 负载因子作用与自动扩容机制

十一、今日总结

  1. 哈希表依靠哈希函数实现 O (1) 级访问
  2. 拉链法是实际开发最主流冲突解决方案
  3. 刷题优先使用 unordered_map 做频次统计、配对查找
  4. 无序选哈希,有序选红黑树容器
相关推荐
_清歌3 小时前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局3 小时前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象3 小时前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局3 小时前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法
统计实现局3 小时前
dqrsl 拆解:拿着 QR 结果能算出哪 5 种东西
算法
统计实现局4 小时前
为什么 Cholesky 求逆比 Gauss-Jordan 快一倍——行列式溢出防护详
算法
To_OC15 小时前
LC 994 腐烂的橘子:人人都说是 BFS 入门题,我却写了三遍才过
javascript·算法·leetcode
金銀銅鐵18 小时前
[Python] 扩展欧几里得算法
python·数学·算法
To_OC21 小时前
LC 200 岛屿数量:经典 DFS 入门题,我第一次写居然连方向都搞错了
javascript·算法·leetcode