跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

c++中set和map的区别_c++关联容器选择指南【对比】

std::set和std::map底层均基于红黑树,性能相同;区别仅在于set存储单一元素(键即值),map存储键值对;选择依据是是否需要键值分离。 set 和 map 的底层实现完全一样 它们都基于红黑树(
std::set
和
std::map
默认都是
std::less
比较 + 红黑树),插入、查找、删除都是
O(log n)
,内存布局和迭代器行为也一致。区别只在「存什么」和「怎么查」。 常见误解是“
set
慢一点”,其实只要不滥用
operator[]
或
at()
,两者性能几乎无差别。 用 set 还是 map?看你要不要「键值分离」
std::set
存的是单一元素,这个元素既是键也是值;
std::map
存的是 键值对 ,键用于排序和查找,值用于存储附加信息。 要判断某个整数是否出现过 → 用
std::set
要查“学号 → 姓名”映射 → 用
std::map
要按字符串长度排序,但只存字符串本身 → 不能直接用
set
,得自定义比较器:
std::set
insert / find / erase 的参数和返回值差异很关键
set::insert
接收单个
T
,返回
std::pair
;
map::insert
接收
std::pair
或
std::initializer_list
,返回类型相同但语义不同:bool 表示「键是否新增」而非「元素是否新增」。 立即学习 “ C++免费学习笔记(深入) ”;
map::find
返回
iterator
到键值对,解引用后是
std::pair&
;
set::find
返回
iterator
到元素本身。 容易踩的坑: 误用
map[key] = value
触发默认构造(如果
Value
不可默认构造会编译失败) 用
map.find(key) != map.end()
判断存在性是对的,但用
map[key]
再判断是否为默认值是错的——它已悄悄插入
set
没有
operator[]
,写
s[0]
直接编译失败 multiset / multimap 是唯一需要认真考虑的分支 当允许重复键时,
std::multiset
和
std::multimap
才有意义。它们不提供
operator[]
,且
find()
只返回一个迭代器(哪怕有多个匹配),必须用
equal_range()
遍历全部。 注意:
multimap
的键依然不可修改(因为要维持红黑树结构),所以
iter->first
是 const,但
iter->second
可改。 如果你只是想“按 key 分组存多个 value”,有时用
std::map>
更直观、更易读,尤其当 value 数量少且增删不频繁时。 真正需要
multimap
的典型场景是:频繁按 key 查找 + 同时需要按插入顺序或值大小做范围遍历 —— 这时候红黑树的天然有序性才有不可替代的优势。

相关文章