【STL】set、multiset、unordered_set、unordered_multiset 的区别

在 C++ STL 中,setmultiset 是经常使用的关联式容器,而从 C++11 开始,又引入了 unordered_setunordered_multiset

很多同学在学习时常常会混淆它们的区别,今天我们就来系统梳理一下。


1. set

  • 特点

    • 元素 唯一
    • 元素 自动排序(默认升序,可自定义比较函数)
    • 底层实现:红黑树(平衡二叉搜索树)
  • 示例

c++ 复制代码
#include <set>
#include <iostream>
using namespace std;

int main() {
    set<int> s;
    s.insert(3);
    s.insert(1);
    s.insert(3); // 插入失败,元素必须唯一
    for (int v : s) cout << v << " "; // 1 3
}

2. multiset

  • 特点

    • 元素 允许重复
    • 元素 自动排序
    • 底层实现:红黑树
  • 示例

c++ 复制代码
#include <set>
#include <iostream>
using namespace std;

int main() {
    multiset<int> ms;
    ms.insert(3);
    ms.insert(1);
    ms.insert(3); // 插入成功,可重复
    for (int v : ms) cout << v << " "; // 1 3 3
}
  • 删除操作差异

    c++ 复制代码
    multiset<int> ms = {1, 2, 2, 3};
    ms.erase(2);  // 删除所有 key=2 的元素
    // 如果只想删除一个,可以用迭代器:
    auto it = ms.find(2);
    if (it != ms.end()) ms.erase(it);

3. unordered_set

  • 特点

    • 元素 唯一
    • 元素 无序存储(不保证顺序)
    • 底层实现:哈希表
    • 查找、插入、删除 平均 O(1) ,性能通常比 set 更高
  • 示例

c++ 复制代码
#include <unordered_set>
#include <iostream>
using namespace std;

int main() {
    unordered_set<int> us;
    us.insert(5);
    us.insert(1);
    us.insert(5); // 插入失败,元素必须唯一
    for (int v : us) cout << v << " "; // 输出顺序不固定
}

4. unordered_multiset

  • 特点

    • 元素 允许重复
    • 元素 无序存储
    • 底层实现:哈希表
    • 查找、插入、删除 平均 O(1)
  • 示例

c++ 复制代码
#include <unordered_set>
#include <iostream>
using namespace std;

int main() {
    unordered_multiset<int> ums;
    ums.insert(5);
    ums.insert(5);
    ums.insert(1);
    for (int v : ums) cout << v << " "; // 输出顺序不固定
}

5. 四者对比总结

其实这四者的区别很明显也很容易懂。只要不去涉及底层原理,看下面这张表就行了。

容器类型 元素唯一性 是否有序 底层结构 插入/查找/删除复杂度
set 唯一 有序 红黑树 O(log n)
multiset 可重复 有序 红黑树 O(log n)
unordered_set 唯一 无序 哈希表 平均 O(1),最坏 O(n)
unordered_multiset 可重复 无序 哈希表 平均 O(1),最坏 O(n)

总结一下

就是带有multi的就是可以有重复元素;带有unordered就是无序,然后性能更好点。


6. 使用场景的建议

  • set :需要保持元素唯一 ,且要有序(如 ID 集合、排行榜)。
  • multiset :需要存储重复元素 ,且要有序(如成绩表、频率统计)。
  • unordered_set :需要元素唯一 ,且更关心性能,不在意顺序(如哈希去重)。
  • unordered_multiset :需要存储重复元素 ,且更关心性能,不在意顺序(如计数场景)。

相关推荐
Tairitsu_H14 小时前
[LC优选算法#17] 链表 | 合并 K 个升序链表 | K个⼀组翻转链表
数据结构·算法·链表
_olone14 小时前
Luogu P2704 [NOI2001] 炮兵阵地
c++·算法·状压dp
c2385615 小时前
互斥锁高频面试题全解:从基础概念到底层实现,一文通关
java·c++·面试·职场和发展
nianniannnn15 小时前
c++复习自存--继承
开发语言·c++
kebidaixu15 小时前
两轮BMS 防打火策略详解
算法
wabs66616 小时前
关于动态规划【力扣1035.不相交的线和53.最大子数组和的思考】
算法·leetcode·动态规划
退休倒计时16 小时前
【每日一题】LeetCode 199. 二叉树的右视图 TypeScript
算法·leetcode·typescript
可编程芯片开发16 小时前
通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器
算法
kebidaixu16 小时前
两轮BMS 短路保护策略详解
算法
王老师青少年编程16 小时前
2026年6月GESP真题及题解(C++二级):完全平方数计数
c++·题解·真题·gesp·二级·2026年6月·完全平方数计数