news 2026/4/16 16:34:56

C++:unordered_map/unordered_set 使用指南(差异、性能与场景选择)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++:unordered_map/unordered_set 使用指南(差异、性能与场景选择)

一. 核心认知:unordered 系列容器是什么?

unordered_map 和 unordered_set 是 C++11 引入的关联式容器,底层基于哈希表(哈希桶)实现,核心特点如下:

  • 存储特性:unordered_set 存储单个 key(去重 + 无序),unordered_map 存储 key-value 对(key 去重 + 无序);
  • 效率:增删查改平均时间复杂度 O (1),最坏情况 O (N)(哈希冲突严重时);
  • 迭代器:单向迭代器(不支持 – 操作),遍历结果无序;
  • 对 key 的要求:需支持 “转换为整形”(哈希函数需求)和 “相等比较”(冲突判断需求)。

二. 模板参数与基础接口

2.1 模板参数

一般来说,后面三个参数我们都不需要传。

2.2 核心接口(与 map/set 高度一致)

无论是unordered_map还是unordered_set,核心接口与 map/set 完全兼容,上手零成本:(这里仅展示部分接口,剩下的可以看看文档,还有些和map/set不一样的后续讲实现的时候还会再进行补充的

unordered_set 核心接口

#include <unordered_set> using namespace std; int main() { unordered_set<int> us; // 插入(返回pair<iterator, bool>,bool标记是否插入成功) us.insert(10); us.insert({ 20, 30, 40 }); // 查找(返回迭代器,未找到返回end()) auto it = us.find(20); if (it != us.end()) { // 找到处理 } // 删除(按key删除,返回删除个数) us.erase(30); // 其他常用接口 us.size(); // 元素个数 us.empty(); // 是否为空 us.clear(); // 清空容器 }

unordered_map 核心接口:

#include <unordered_map> using namespace std; int main() { unordered_map<string, int> um; // 插入 um.insert({ "sort", 1 }); um.insert(make_pair("left", 2)); // []运算符(插入+访问/修改,最常用) um["right"] = 3; // 插入 um["left"] = 22; // 修改 // 查找 auto it = um.find("sort"); if (it != um.end()) { cout << it->first << ":" << it->second << endl; } // 删除 um.erase("right"); }

2.3 支持冗余的版本:unordered_multiset/unordered_multimap

与 multiset/multimap 类似,支持 key 重复:

三. 关键差异:unordered 系列 vs map/set

对比维度unordered_map/unordered_setmap/set
底层结构哈希表(数组 + 链表/红黑树)有序(按 key 默认升序排列)
元素顺序无序(取决于哈希函数)有序(按 key 默认升序排列)
时间复杂度平均O(1),最差O(n)稳定O(logN)
迭代器特性单向迭代器(仅支持向前遍历)双向迭代器(支持向前/向后遍历)
对 Key 的要求1. 支持==比较
2. 可计算哈希值
支持<比较(或自定义严格弱序)
内存占用较高(需预留桶空间减少冲突)较低(树结构紧凑,无预留开销)
数据分布数据分散在桶中数据在树结构中平衡分布
主要优势极速查找(常数级平均时间)有序遍历、稳定性能
典型场景高频查询、缓存系统、去重操作需要有序数据、范围查询、顺序相关操作

选择建议:

四. 性能实测:谁更快

测试代码(核心逻辑)

// (测试环境:VS2022,Release 模式): #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<unordered_set> #include<unordered_map> #include<set> using namespace std; void test_unset1() { const size_t N = 1000000; unordered_set<int> us; set<int> s; vector<int> v; v.reserve(N); srand(time(0)); for (size_t i = 0; i < N; ++i) { v.push_back(rand()); // N比较大时,重复值比较多 //v.push_back(rand() + i); // 重复值相对少 //v.push_back(i); // 没有重复,有序 } size_t begin1 = clock(); for (auto e : v) { s.insert(e); } size_t end1 = clock(); cout << "set insert:" << end1 - begin1 << endl; size_t begin2 = clock(); us.reserve(N); for (auto e : v) { us.insert(e); } size_t end2 = clock(); cout << "unordered_set insert:" << end2 - begin2 << endl; int m1 = 0; size_t begin3 = clock(); for (auto e : v) { auto ret = s.find(e); if (ret != s.end()) { ++m1; } } size_t end3 = clock(); cout << "set find:" << end3 - begin3 << "->" << m1 << endl; int m2 = 0; size_t begin4 = clock(); for (auto e : v) { auto ret = us.find(e); if (ret != us.end()) { ++m2; } } size_t end4 = clock(); cout << "unorered_set find:" << end4 - begin4 << "->" << m2 << endl; cout << "插入数据个数:" << s.size() << endl; cout << "插入数据个数:" << us.size() << endl << endl; size_t begin5 = clock(); for (auto e : v) { s.erase(e); } size_t end5 = clock(); cout << "set erase:" << end5 - begin5 << endl; size_t begin6 = clock(); for (auto e : v) { us.erase(e); } size_t end6 = clock(); cout << "unordered_set erase:" << end6 - begin6 << endl << endl; } int main() { test_unset1(); return 0; }

三组测试结果

关键结论:

unordered_xxx的哈希相关接口:
BucketsHash policy系列的接口分别是跟哈希桶和负载因子相关的接口,日常使用的角度我们不需要太关注,后面学习了哈希表底层,我们再来看这个系列的接口,一目了然。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 15:27:35

Proteus下载与配置:手把手完成仿真环境搭建

手把手搭建Proteus仿真环境&#xff1a;从下载到联动调试的完整实践指南 在电子设计的世界里&#xff0c;你是否曾因一个电阻接错、一段代码逻辑出错&#xff0c;导致整个开发板“冒烟”&#xff1f;又是否为买不起昂贵的开发工具而苦恼&#xff1f;别担心&#xff0c; Prote…

作者头像 李华
网站建设 2026/4/16 12:59:36

大模型部署瓶颈怎么破?用TensorRT镜像实现低延迟高吞吐

大模型部署瓶颈怎么破&#xff1f;用TensorRT镜像实现低延迟高吞吐 在今天的AI应用战场上&#xff0c;一个模型“训得好”只是第一步。真正决定产品成败的&#xff0c;是它能不能在真实业务场景中“推得动”——响应够不够快、每秒能处理多少请求、资源开销是否可控。 尤其是…

作者头像 李华
网站建设 2026/4/13 8:55:04

厦门狄耐克以脑机交互技术,重塑全民脑健康新范式

大脑&#xff0c;是人类最精密的器官&#xff0c;也是健康中国战略中最不容忽视的“头等大事”。当前&#xff0c;我国超2.9亿人饱受失眠困扰&#xff0c;阿尔茨海默病等认知障碍发病率持续攀升——脑健康危机&#xff0c;正悄然侵蚀社会活力与个体尊严。厦门狄耐克以科技为盾、…

作者头像 李华
网站建设 2026/4/3 14:29:38

STM32串口通信详解:UART协议全面讲解

从零开始玩转STM32串口&#xff1a;不只是“打印Hello World”那么简单 你有没有过这样的经历&#xff1f;代码写完&#xff0c;烧录进板子&#xff0c;满怀期待地打开串口助手——结果屏幕一片空白。或者更糟&#xff0c;收到一堆乱码&#xff0c;像是外星人发来的密文。 别急…

作者头像 李华
网站建设 2026/4/16 16:10:39

树莓派课程设计小项目解析:4B平台下GPIO操作全面讲解

树莓派4B实战入门&#xff1a;从点亮LED到掌握GPIO高级控制你有没有试过用代码让一个小小的LED灯闪烁&#xff1f;听起来简单&#xff0c;但这一步&#xff0c;正是嵌入式开发的起点。在“树莓派课程设计小项目”中&#xff0c;GPIO操作就是那把打开硬件世界大门的钥匙。尤其是…

作者头像 李华