map基于红黑树实现,元素有序,插入查找复杂度o(log n);unordered_map基于哈希表,无序,理想情况操作复杂度为o(1)。1. map自动按键排序,适用于需顺序遍历或范围查询的场景;unordered_map不维护顺序,适合频繁增删查操作且无需顺序的情况。2. 性能上,map适用于有序需求,unordered_map在无序需求下更快。3. 自定义类型作key时,map需提供比较逻辑,unordered_map需提供哈希函数和等于判断。选择依据是是否需要排序、速度要求及是否涉及自定义类型。

在C++中,map和unordered_map是最常用的关联容器之一,它们都用来存储键值对(key-value pairs),但在底层实现、性能特点以及适用场景上有着显著差异。如果你关心程序的效率或者需要根据具体情况选择合适的数据结构,理解它们之间的区别就非常重要。

1. 底层实现不同:红黑树 vs 哈希表
这是两者最核心的区别。

-
map是基于红黑树实现的,这意味着它内部的元素是按照 key 的顺序进行排序存储的。 -
unordered_map则是基于哈希表实现的,不保证元素的顺序,只提供快速的查找能力。
因为这个差异,map 插入和查找的时间复杂度是 O(log n),而 unordered_map 在理想情况下可以达到 O(1),但极端情况下可能退化为 O(n)(比如大量哈希冲突)。
立即学习“C++免费学习笔记(深入)”;
2. 是否自动排序:有序 vs 无序
-
map默认会按照 key 的升序排列所有元素。这在你需要按顺序遍历键的时候非常有用,例如输出电话簿的字母顺序列表。 -
unordered_map不维护任何顺序,插入顺序也不会被保留。如果你不关心顺序,只是想快速存取数据,那它更合适。
举个例子:

mapm = {{3,"three"}, {1,"one"}, {2,"two"}}; // 遍历时顺序是 {1, one}, {2, two}, {3, three} unordered_map um = {{3,"three"}, {1,"one"}, {2,"two"}}; // 遍历顺序不确定
3. 性能对比:什么时候用哪个?
选择使用哪一个,主要看你的使用场景:
- 如果你经常需要按键排序访问,或者做范围查询(比如找某个区间的 key),那应该用
map。 - 如果你只需要频繁地进行插入、查找和删除操作,并且不关心顺序,那么
unordered_map更快。
常见操作性能对比(平均情况):
| 操作 | map | unordered_map |
|---|---|---|
| 插入 | O(log n) | O(1) |
| 查找 | O(log n) | O(1) |
| 删除 | O(log n) | O(1) |
当然,unordered_map 的性能也依赖于哈希函数的质量和负载因子的设置。
4. 自定义类型的支持:需要自己处理比较或哈希逻辑
- 对于
map,如果你使用自定义类型作为 key,必须提供一个比较函数或重载运算符。 - 对于
unordered_map,则需要提供哈希函数和等于判断函数(即==)。
举个简单的例子,如果你想用 string 以外的类型当 key,比如结构体:
struct MyKey {
int a;
bool operator<(const MyKey& other) const { return a < other.a; }
};
// 用于 map
// 而对于 unordered_map,除了 operator== 外,还需要一个哈希函数类:
struct MyKeyHash {
size_t operator()(const MyKey& k) const {
return hash()(k.a);
}
}; 这部分虽然看起来麻烦,但是一旦写好就可以复用。
基本上就这些。总结来说,map 和 unordered_map 各有优势,关键在于你的具体需求:是否需要排序、对速度的要求有多高、是否涉及自定义类型等。选择合适的容器能让代码既高效又简洁。










