两个无序关联容器将底层的红黑树变成了哈希表。
一、核心定位(一句话)
unordered_set= 无序、更快、不排序 的setunordered_map= 无序、更快、不排序 的map
它们底层是哈希表,所以:
- 平均插入 / 查找 / 删除 O (1)(比 set/map 快很多)
- 不保证顺序,遍历出来是乱的
- 用法几乎和 set/map 完全一样
二、unordered_set 详细说明(基于 set)
1. 和 set 相同的地方(你已经会了)
- 元素唯一,不能重复
- 有
insert()erase()find()count() - 迭代器遍历
- 元素不能修改(必须删了重插)
2. 和 set 不同的地方(必须记住)
-
无序 插入 {3,1,2}set 输出:1 2 3unordered_set 输出:乱序(可能 2 1 3 或其他)
-
速度更快 set:O(log n)unordered_set:平均 O (1)
-
不支持 lower_bound /upper_bound因为没有顺序,无法范围查找。
-
头文件不同
cpp#include <unordered_set>
3. 常用代码(和 set 一模一样)
cpp
unordered_set<int> us;
us.insert(5); // 插入
us.erase(5); // 删除
auto it = us.find(5); // 查找
if(it != us.end())
cout << *it << endl;
4. 特别注意
- 遍历顺序不固定
- 千万不要依赖顺序
- 性能比 set 好很多
三、unordered_map 详细说明(基于 map)
1. 和 map 相同的地方
- 键唯一
- 支持
[]、at()、insert()、erase()、find() - 可以修改值 ,不能修改键
- 用法几乎一样
2. 和 map 不同的地方
-
无序 map 按键排序unordered_map 不排序
-
速度更快 map:O(log n)unordered_map:平均 O (1)
-
不支持 lower_bound /upper_bound
-
头文件不同
cpp#include <unordered_map>
3. 代码示例(和 map 一样)
cpp
unordered_map<int, string> um;
um[1] = "one"; // 插入/修改
um.insert({2, "two"});
auto it = um.find(1);
if(it != um.end())
cout << it->second << endl;
四、最关键的 4 个区别(必背)
1. 顺序
- set / map:有序
- unordered:无序
2. 速度
- set / map:O(log n)
- unordered:平均 O (1) 更快
3. 底层结构
- set /map:红黑树
- unordered:哈希表
4. 范围查找
- set /map:支持
lower_bound - unordered:不支持