【C++】哈希表:简单易懂的核心讲解(含实战用法)

news/2025/12/7 15:14:35/文章来源:https://www.cnblogs.com/Kakakak/p/19318185
哈希表(Hash Table)是 C++ 中高效的键值对(key-value)存储结构,核心优势是 插入、查找、删除操作的平均时间复杂度接近 O (1)—— 比数组查找(O (n))、有序容器(如 map,O (log n))快得多,日常开发中常用来解决 “快速查找 / 去重 / 统计” 类问题。

一、先搞懂:哈希表到底是什么?(大白话版)

你可以把哈希表想象成一个 “带编号的快递柜”
  • key(键):快递的 “取件码”(唯一标识);
  • value(值):快递本身(要存储的数据);
  • 哈希函数:把 “取件码”(key)转换成 “柜子编号”(数组索引)的规则;
  • 数组 + 链表 / 红黑树:柜子的存储结构(数组是主体,链表 / 红黑树解决 “多个取件码对应同一个柜子” 的冲突问题)。
举个例子:要存储 “学生学号→学生姓名”,哈希函数可以是 “学号 mod 100”—— 学号 202501 对应柜子 1,学号 202502 对应柜子 2,直接按编号找柜子,不用逐个遍历,这就是 O (1) 效率的核心。

二、C++ 中怎么用哈希表?(重点:STL 容器)

C++ 标准库没有直接叫 “HashTable” 的类,但提供了 2 个核心哈希容器,直接用就行:
容器 特点(核心区别) 适用场景
unordered_map 存储 key-value 对,key 唯一,无序 快速查找 / 映射(如字典、缓存)
unordered_set 只存储 key,key 唯一,无序 快速去重 / 判断元素是否存在

补充:和有序容器的区别

  • map/set 是有序的(基于红黑树),查找效率 O (log n);
  • unordered_map/unordered_set 是无序的(基于哈希表),平均 O (1),但最坏 O (n)(冲突严重时),且内存占用略高。

三、实战代码:3 个最常用场景

场景 1:用 unordered_map 做 “键值映射”(如字典 / 缓存)

比如存储 “单词→释义”,快速根据单词查意思:
cpp
 
运行
 
 
 
 
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;int main() {// 1. 定义哈希表:key=string(单词),value=string(释义)unordered_map<string, string> dict;// 2. 插入元素(3种方式)dict["apple"] = "苹果";          // 直接赋值(最简洁)dict.insert({"banana", "香蕉"}); // insert 函数(键不存在时插入)dict.emplace("orange", "橙子");  // emplace(效率更高,直接构造对象)// 3. 查找元素(核心:快速查找)string key = "apple";if (dict.find(key) != dict.end()) { // find 返回迭代器,找不到返回 end()cout << key << " → " << dict[key] << endl; // 输出:apple → 苹果} else {cout << "未找到该单词" << endl;}// 4. 遍历哈希表(无序)for (auto& pair : dict) { // pair.first 是 key,pair.second 是 valuecout << pair.first << " : " << pair.second << endl;}// 5. 删除元素dict.erase("banana"); // 按 key 删除return 0;
}
 

场景 2:用 unordered_set 去重 / 判断存在

比如给一个数组去重,或快速判断某个数是否在数组中:
cpp
 
运行
 
 
 
 
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;int main() {vector<int> nums = {1, 2, 2, 3, 3, 3, 4};unordered_set<int> unique_nums;// 去重:插入时自动忽略重复 keyfor (int num : nums) {unique_nums.insert(num); // 最终只存 1,2,3,4}// 判断元素是否存在int target = 3;if (unique_nums.count(target)) { // count 返回 0 或 1(key 唯一)cout << target << " 存在" << endl; // 输出:3 存在}// 遍历去重后的结果for (int num : unique_nums) {cout << num << " "; // 输出:1 2 3 4(顺序不确定)}return 0;
}
 

场景 3:用哈希表统计频率(如计数问题)

比如统计字符串中每个字符出现的次数:
cpp
 
运行
 
 
 
 
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;int main() {string s = "hello world";unordered_map<char, int> freq; // key=字符,value=出现次数// 统计频率for (char c : s) {freq[c]++; // 不存在的 key 会自动初始化为 0,再 ++}// 输出结果for (auto& pair : freq) {cout << "'" << pair.first << "' : " << pair.second << "次" << endl;}// 部分输出:'h':1次, 'e':1次, 'l':3次, 'o':2次...return 0;
}
 

四、关键注意点(避坑指南)

  1. key 必须可哈希:C++ 中默认支持的 key 类型:intstringdouble 等基础类型;自定义类型(如结构体)作为 key 时,需要手动重载 == 运算符(判断键是否相等)和提供哈希函数(否则编译器报错)。
  2. 无序性unordered_* 容器的遍历顺序和插入顺序无关,若需要有序,应改用 map/set
  3. 冲突问题:哈希表的效率依赖 “哈希函数的好坏”—— 好的哈希函数能减少 “多个 key 对应同一个索引” 的冲突;STL 已内置优化,日常开发不用手动处理冲突。
  4. 性能权衡:追求极致查找速度、不关心顺序 → 用 unordered_map/unordered_set;需要有序存储、允许略低效率 → 用 map/set

总结

哈希表是 C++ 中 “以空间换时间” 的典范,核心价值是 O (1) 级别的查找 / 插入 / 删除。日常开发中,只要遇到 “键值映射、去重、频率统计” 类问题,优先用 unordered_map 或 unordered_set,简单直接又高效!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/991508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PFLS

作者介绍: 来自PFLS。现在7年5班。

Dify 自建部署完全指南:从上手到放弃到真香

本文记录了一个开发者在企业内部部署Dify AI平台的两周血泪史。从老板突然要求搭建私有化AI平台开始,评估了Coze、FastGPT等方案后选择了Dify,部署过程充满挑战……故事的开始:就想要个听话的 AI 应用平台 几个月前…

工业设计必备工具:3ds Max 2025 三维建模 影视特效 下载安装教程

Autodesk 3ds Max 是一款专业的三维建模、动画和渲染软件,广泛应用于游戏开发、影视特效、建筑可视化和产品设计等领域,它凭借功能强大、操作灵活且兼容性强的特点,成为游戏开发、影视制作、建筑设计等多个领域的主…

组合计数题没做

确实没做。确实没做。

城市内涝监测架构-恒星物联解决方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

院长码上办-患者投诉接办管理系统

院长码上办-患者投诉接办管理系统 www.yzmsb.com

2025上海黛丽汀立体停车设备厂家实力榜:智能垂直升降技术领跑,六家高潜力本土品牌深度解析

2025上海黛丽汀立体停车设备厂家实力榜:智能垂直升降技术领跑,六家高潜力本土品牌深度解析 随着中国城市化进程的不断深化,“停车难”已成为制约城市发展、影响居民生活质量的核心痛点之一。在这一背景下,立体停车…

代数数论与模块格基础学习

代数数论与模块格基础学习代数数论与模块格完整学习指南 目录学科概述与学习路径前置知识准备代数数论核心理论模块格理论基础高级算法与技术密码学应用最新研究进展学习资源与实践1. 学科概述与学习路径 1.1 代数数论…

【Azure App Service】部署在应用服务上的WebJob中,为何会多出一个名为DaaS的 WebJob呢?

问题描述 在 Azure App Service 环境中,发现App Service服务在无人操作的情况下,凭空出现了一个名为 “DaaS” 的 WebJob。这个作业是做什么的呢?是否会影响应用性能或安全性? 问题解答 DaaS 全称 Diagnostics as …

2025上海立体车库厂家实力榜:黛丽汀以智能垂直循环技术领跑,六家高潜力本土品牌深度解析

2025上海立体车库厂家实力榜:黛丽汀以智能垂直循环技术领跑,六家高潜力本土品牌深度解析 随着中国城市化进程的不断深化,城市核心区域的土地资源日益稀缺,“停车难”已成为制约城市发展、影响居民生活质量的普遍性…

spec kit 探索性问答

目录1. 结论(短答)2. 当你“需求没想好”时,如何正确使用 specify模式 A:探索式需求(推荐)模式 B:半成品需求 → 交给 AI 整理模式 C:需求极不确定,但你想快速试验代码生成3. 什么时候不建议执行 specify4. 推…

R语言保存file路径问题

R 工作目录与文件路径问题全解 在使用 R(尤其是 RStudio)进行数据可视化和文件操作时,工作目录与文件路径的设置常常会让人困惑。本文将详细解释相关概念,并给出实用的解决方法。 一、工作目录与 R 文件路径为何不…

退役入生前最后一道题

退役的 OIer 在搞笑椅子 OJ 上的最后一发提交。用户名 退役比赛 提交题目 提交状态 / 分数 提交时间张轩程 CSP-S2024 [USACO22OPEN] Hoof and Brain P 95 Time Exceeded 2024-11-20 17:16:19wanghaoyan123 NOIP2024 【…

2025最新深圳/惠州输送线厂家TOP5推荐!深圳惠州地区组装线/装配线/生产线/输送线/老化线选购优质供应商评测

随着工业自动化的快速发展,输送线、生产线及装配线作为工业生产中的关键设备,其性能和质量直接影响企业的生产效率与产品品质。本榜单基于技术实力、行业适配性、服务能力三大维度,结合市场反馈与行业数据,对2025年…

【Java】面向对象基础

目录前言内容概览更新记录面向对象的概念对象的执行原理对象的注意点this关键字构造器封装实体类JavaBean 前言 1.之前学过,因此本文是个人复习笔记,为视频的总结以及个人思考,可能不是很详细。 2.教程是b站黑马程序…

归并分治模板

翻转对 class Solution { public:int findpairs(vector<int> &nums, int l, int r) {int mid = (l + r) >> 1;int i = l, j = mid + 1;int res = 0;for (; i <= mid; ++i) {while (j <= r &…

2025燕窝品牌实力排行榜:艾玛琳商贸以溯源科技领衔,六大高潜力燕窝衍生品与礼品企业深度解析

2025燕窝品牌实力排行榜:艾玛琳商贸以溯源科技领衔,六大高潜力燕窝衍生品与礼品企业深度解析 随着健康消费理念的持续深化与国潮文化的兴起,燕窝及其衍生品市场正经历一场深刻的变革。传统单一的干燕窝消费模式,正…

ABC 435 解题报告

A 略。 B 略。 C 记录当前可以弄倒的最远位置,记得和 \(n\) 取 \(\min\)。 D 考虑建反图,然后从每一个黑点开始 dfs 一遍,遇到黑点就停下(因为之后扩展到的点这个黑点一定也可以扩展到)。每个点至多被访问一次,均…

【创作分享】一个简单易用、功能强大的 AI 图片生成工具:NanoEdit(基于Gemini 3.0 Nano Banana Pro)

【创作分享】一个简单易用、功能强大的 AI 图片生成工具:NanoEdit(基于Gemini 3.0 Nano Banana Pro)最近这段时间,我一直在投入一个自己非常喜欢的小项目——NanoEdit。想做这件事的原因其实很简单: 我平时需要生…

街头徒手健身4高阶引体向上

4 高阶引体向上 我刚踏入健身行业时,修过私人教练课程,还读了不少专业教材,就是为了学习最优质的训练方案和最新的健身理念。我在文献中看到大量关于高位下拉器械的介绍,可关于经典实用的引体向上,内容却寥寥无几…