C++的set容器属于标准模板库STL中的关联式容器,底层采用红黑树数据结构实现,默认会按照元素从小到大的顺序自动排序,并且天然支持元素去重,不需要开发者额外编写去重逻辑。它的去重原理是红黑树在插入新元素时,会先比较待插入元素和树中已有元素的大小,如果存在相等的元素就不会执行插入操作,从而实现去重效果。

set容器的基础用法
set的声明与初始化
使用set前需要引入头文件<set>,声明set时需要指定元素的数据类型,初始化可以直接传入初始化列表,也可以通过迭代器范围初始化。下面是基础的声明初始化示例:
#include <iostream>
#include <set>
using namespace std;
int main() {
// 声明并初始化一个int类型的set
set<int> numSet = {3, 1, 2, 2, 3, 4};
// 输出set的大小,去重后应该是4
cout << "set的大小为:" << numSet.size() << endl;
return 0;
}
set的常用操作
set提供了丰富的成员函数支持日常操作,常用的操作包括插入元素、删除元素、遍历元素等,具体说明如下:
- insert(val):向set中插入元素val,如果元素已存在则插入失败,返回pair<iterator, bool>类型的结果,第二个参数表示是否插入成功。
- erase(val):删除set中值为val的元素,如果元素不存在则不做任何操作。
- erase(iterator):通过迭代器删除指定位置的元素。
- clear():清空set中的所有元素。
- size():返回set中当前元素的数量。
- empty():判断set是否为空,为空返回true,否则返回false。
下面是通过迭代器遍历set的示例,由于set是有序的,遍历输出的元素会按照从小到大排列:
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> numSet = {5, 2, 8, 2, 5, 1};
// 遍历输出set中的元素
cout << "set中的元素为:";
for (auto it = numSet.begin(); it != numSet.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
set容器的去重实例
set的去重是自动完成的,不需要开发者手动编写去重逻辑,只需要把元素插入到set中,重复的元素会被自动过滤。下面是一个完整的去重示例,演示如何对一个包含重复元素的数组进行去重:
#include <iostream>
#include <set>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {1, 3, 2, 3, 5, 2, 1, 4};
// 将vector中的元素插入到set中,自动去重排序
set<int> uniqueNums(nums.begin(), nums.end());
cout << "去重后的元素为:";
for (int num : uniqueNums) {
cout << num << " ";
}
cout << endl;
// 尝试插入重复元素
auto result = uniqueNums.insert(3);
if (!result.second) {
cout << "元素3已存在,插入失败" << endl;
}
return 0;
}
set容器的元素查找实例
set提供了find()成员函数用于查找指定元素,查找的时间复杂度为O(log n),效率远高于遍历数组查找。如果找到元素,返回指向该元素的迭代器,否则返回end()迭代器。下面是元素查找的完整示例:
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> numSet = {10, 20, 30, 40, 50};
int target = 30;
// 查找目标元素
auto it = numSet.find(target);
if (it != numSet.end()) {
cout << "找到元素" << target << ",值为:" << *it << endl;
} else {
cout << "未找到元素" << target << endl;
}
// 查找不存在的元素
target = 60;
it = numSet.find(target);
if (it == numSet.end()) {
cout << "未找到元素" << target << endl;
}
return 0;
}
set使用的注意事项
使用set时需要注意以下几点:
- set中的元素是只读的,不能通过迭代器修改元素的值,因为修改元素可能破坏红黑树的有序性。
- 如果需要存储自定义类型的元素,需要为自定义类型重载小于运算符<,或者给set传入自定义的比较函数,否则无法完成排序和去重。
- 如果需要保留重复元素,可以使用multiset容器,它的用法和set基本一致,只是允许存储重复元素。
set的底层红黑树结构保证了插入、删除、查找操作的时间复杂度都是O(log n),适合需要频繁查找和去重的场景,但是它的空间开销比数组和vector更大,需要根据实际需求选择使用。