C++ multiset数据结构的使用情况说明
在什么情况下需要使用 multiset
?
在这篇文章中,我们先简单回顾一下 multiset
的特性,然后结合实际场景来分析。
multiset 的特性(C++ STL 为例)
-
自动有序:
- 元素会按照比较函数(默认是升序)自动排序。
- 不需要手动调用
sort
。
-
允许重复元素:
- 不同于
set
(不允许重复),multiset
可以有相同值的元素,而且会把它们都存储起来。
- 不同于
-
基于平衡二叉搜索树(通常是红黑树)实现:
- 插入、删除、查找的时间复杂度是 O(log n)。
-
迭代器稳定:
- 插入和删除不会让其他元素的迭代器失效(除了被删除的元素)。
什么时候用 multiset
?
1. 需要维护一个有序集合,且允许重复元素
- 例如存储多个考试成绩,并且需要随时按分数从高到低(或低到高)输出。
- 不适合用
set
(会去重),用vector
每次排序又太慢。
multiset<int> scores;
scores.insert(90);
scores.insert(85);
scores.insert(90); // 重复分数也能插入
2. 随时插入、删除,并保持有序
multiset
适合动态场景:- 游戏排行榜
- 股票价格实时排名
- 数据流的中位数维护
multiset<int> prices;
prices.insert(100);
prices.erase(prices.find(100));
(注意 erase(value)
会删除所有等于该值的元素,如果只想删一个需要 erase(iterator)
)
3. 需要高效统计某个元素的出现次数
- 用
count()
在 O(log n) 内查看某个值的数量。 - 比如投票系统统计某个候选人票数。
4. 实现优先队列但需要支持删除任意元素
- 普通
priority_queue
不能快速删除中间元素,而multiset
可以。
5. 需要区间查询
lower_bound()
/upper_bound()
可以快速找区间内的元素,比如:- 找出分数在 [80, 90] 的学生数量
- 找出大于某个值的最小元素
✅ 总结简单记忆
- 如果你需要有序 + 允许重复 + 动态插入删除 → 用
multiset
- 如果只是有序 + 不允许重复 → 用
set
- 如果是频率统计 + 无序 → 用
unordered_multiset
或unordered_map