当前位置: 首页 > news >正文

为什么哈希表能 O(1) 查找?——C++ 哈希基础入门

为什么哈希表能 O(1) 查找?——C++ 哈希基础入门

1. 引言

在学习 C++ STL 时,我们经常会遇到 std::unordered_mapstd::unordered_set 这样的容器。相比于 mapO(logN) 查找,unordered_map 能够在 平均 O(1) 的时间复杂度内完成插入和查找操作。
但问题来了:为什么它能做到 O(1)?真的所有情况下都能这么快吗?

本文通过类比与代码实例,带你从直观到原理逐步理解哈希表的奥秘。

2. 哈希表的形象理解

想象一下:

  • 你住在一个大宿舍楼,每个人都要把钥匙放进钥匙柜。

  • 如果把钥匙随便放,找的时候要一把一把翻,效率和 vector 的线性查找差不多。

  • 但聪明的宿管阿姨设计了一个 规则:每个钥匙编号经过一个公式(哈希函数)计算,直接决定放在哪个柜子里。

  • 这样,每次找钥匙的时候,只要按照相同的公式算出柜号,就能立刻拿到。

这个“公式”就是 哈希函数,而“钥匙柜”就是 哈希表的桶(bucket)

3. 哈希表的基本结构

哈希表由两部分组成:

  1. 哈希函数(Hash Function):将 Key 映射为整数。

  2. 桶数组(Bucket Array):用来存储数据的容器,每个桶相当于一个格子。

公式很简单:
index=hash(key)mod  bucketcountindex=hash(key)mod  bucket_count index=hash(key)mod  bucket_countindex = hash(key) \mod bucket\_count index=hash(key)mod  bucketcountindex=hash(key)modbucket_count
这样 Key 会被直接映射到某个桶中,查找和插入只需要 一次计算 + 一次访问,因此是 O(1)。

4. 直观示意图

          +-------------------+
Key ----> |   哈希函数 hash() | ----> index = hash(key) % bucket_count+-------------------+|v+--------------------------------------+
Buckets: |  0  |  1  |  2  |  3  |  4  |  5 ...|+--------------------------------------+|                |v                v[Alice:1001]     [Bob:1002]
  • Key(如 “Alice”)经过哈希函数,得到一个整数。

  • 取模运算决定它放在哪个 桶(bucket)

  • 每个桶里存储一个或多个键值对。

  • 查找时同样经过哈希函数,直接跳到对应的桶里取值。

5. C++ 代码示例

来看一个实际代码:

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <chrono>
using namespace std;int main() {unordered_map<string, int> idMap;idMap["Alice"] = 1001;idMap["Bob"]   = 1002;idMap["Cathy"] = 1003;cout << "Alice 的学号是: " << idMap["Alice"] << endl;cout << "Bob 的学号是: "   << idMap["Bob"]   << endl;// 对比 vector 线性查找vector<pair<string,int>> idVec = {{"Alice",1001},{"Bob",1002},{"Cathy",1003}};string query = "Cathy";auto start = chrono::high_resolution_clock::now();for (auto &p : idVec) {if (p.first == query) {cout << "Cathy 的学号是: " << p.second << endl;}}auto end = chrono::high_resolution_clock::now();cout << "vector 查找耗时(ns): " << chrono::duration_cast<chrono::nanoseconds>(end-start).count() << endl;return 0;
}

在数据量较大时,unordered_map 查找几乎是瞬间完成,而 vector 查找会随元素数量线性增加。

6. 哈希表真的总是 O(1) 吗?

并不是。虽然哈希表平均是 O(1),但在以下情况下可能退化:

  • 哈希函数不好:导致大量 Key 落在同一个桶里,冲突严重。

  • 装载因子过高:数据太多,桶太少,会频繁 rehash。

  • 极端情况:理论上可能退化为 O(N)。

这就像宿舍钥匙柜:如果所有人都被分到同一个柜子,那找钥匙就变得非常慢。

7. 小结

  • 哈希表通过 哈希函数 + 桶数组 实现 Key 到存储位置的直接映射。

  • 在平均情况下,查找和插入只需要 O(1) 时间。

  • C++ 提供了 unordered_mapunordered_set 来实现哈希表。

  • 但性能依赖于哈希函数质量和装载因子,极端情况下可能退化。


文章转载自:

http://X7TK7CCA.wffxr.cn
http://ZzjFXsfe.wffxr.cn
http://mpLK9H5o.wffxr.cn
http://sYCQdwPo.wffxr.cn
http://5nMC62oR.wffxr.cn
http://bkmPy3T0.wffxr.cn
http://PMbuGL1z.wffxr.cn
http://tW1DFGbB.wffxr.cn
http://4wgCqUJP.wffxr.cn
http://IaaJv6sJ.wffxr.cn
http://8GoZ7VlZ.wffxr.cn
http://qoRuCme7.wffxr.cn
http://GPEbGP9w.wffxr.cn
http://51D5L5NW.wffxr.cn
http://6EMVTDcb.wffxr.cn
http://x4UCUtEL.wffxr.cn
http://fIMhMND2.wffxr.cn
http://UpwJAddN.wffxr.cn
http://vcfhJycj.wffxr.cn
http://BkFPmjcC.wffxr.cn
http://GB4hqKGg.wffxr.cn
http://ydjm6QnM.wffxr.cn
http://wRmbdoJ0.wffxr.cn
http://O5Xa2CZz.wffxr.cn
http://h3viISIK.wffxr.cn
http://P85W2Pfu.wffxr.cn
http://UE1YIpv5.wffxr.cn
http://xc8UB2ES.wffxr.cn
http://KlDKWg6j.wffxr.cn
http://L27p6Ogb.wffxr.cn
http://www.dtcms.com/a/383723.html

相关文章:

  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • 算法——递推求解
  • stm32之点灯
  • Qt---内存管理 对象树(Object Tree)机制
  • 人工智能通识与实践 - 计算机视觉技术
  • GAMES101:现代计算机图形学入门(Chapter1 计算机图形学概述)学习笔记
  • MATLAB 常用函数汇总大全和高级应用总结
  • Knockout.js 任务调度模块详解
  • LeetCode 2414.最长的字母续连续子字符串的长度
  • 当环保遇上大数据:生态环境大数据技术专业的课程侧重哪些领域?
  • 【Ansible】使用角色和Ansible内容集合简化Playbook知识点
  • init / record / required:让 C# 对象一次成型
  • BigemapPro快速添加历史影像(Arcgis卫星地图历史地图)
  • 树莓派操作第一章常用指令
  • Altium Designer(AD24)工作面板的切换与定制
  • 【WebSocket✨】入门之旅(七):WebSocket 的未来发展趋势
  • MySQL——库的操作
  • Redis缓存的常见问题及其解决方案
  • Conda 安装 CUDA Toolkit 解决 nvcc 找不到的问题
  • (二)Django框架常用配置
  • Android开发-数据库SQLite
  • (附源码)基于springboot的幼儿园管理系统
  • 【从零到公网】本地电脑部署服务并实现公网访问(IPv4/IPv6/DDNS 全攻略)
  • VTK基础(01):VTK中的基本概念
  • Sentinel:微服务架构下的高可用流量防卫兵
  • Unity学习----【进阶】TextMeshPro学习(三)--进阶知识点(TMP基础设置,材质球相关,两个辅助工具类)
  • OpenCV:指纹识别
  • map/multimap容器
  • leetcode 966. 元音拼写检查器 中等
  • esp32程序存储结构--自用笔记版