在 C++ STL 中,set 与 multiset 是经常使用的关联式容器,而从 C++11 开始,又引入了 unordered_set 与 unordered_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 :需要存储重复元素 ,且更关心性能,不在意顺序(如计数场景)。