set 集合
集合set
就是数学上的集合,其中的每个元素没有重复的,但是set
中的元素在数据结构中是有序存储的(默认升序),为了高效的实现插入、删除和查找等操作,这与数学上的集合中元素无序性有点区别。
集合set
也是STL
中的一种标准关联容器,其底层数据结构是基于平衡搜索树(红黑树)实现的,插入删除等操作都是通过迭代器指针实现的,不涉及内存操作,因此效率非常高。
1 头文件
集合set
被包含在set
头文件中
include<set>
2 定义和初始化
// 1 使用默认构造函数
set<int> st;//创建一个空的整数集合
// 2 使用初始化列表
set<int> st = {1,2,3,4,5}; // 创建包含整数的集合并初始化
// 3 使用迭代器范围
set<int> st1 = {1,2,3,4};
set<int> st2(st1.begin(),st.end());//利用另一个集合创建
// 4 利用自定义函数创建
struct MyComparator {
bool operator()(const std::string& a, const std::string& b) const {
return a.length() < b.length();
}
};
set<string, MyComparator> st; //改变了默认升序的排序原则
// 5 使用复制函数构造
set<int>s1 = {1,2,4,5};
set<int>st2(st1); //副本构造法
3常用函数
size();// 返回元素个数
empty(); //返回set是否是空的 空返回真
clear(); //清空集合,集合长度为0
begin(); //返回指向集合第一个元素的迭代器 允许++自增和--
end(); //返回指向集合最后一个元素的下一个位置的迭代器
insert(); //插入一个数 按照升序插入,若是已经有元素,返回fasle
find(); //查找一个数 查找成功返回该元素位置的迭代器,否则返回st.end()
count(); //返回某一个数的个数
erase(x); //删除所以x 时间复杂度 O(k + logn)
erase(s.begin(),s.end());//删除一个迭代器
//核心函数!!!
lower_bound(x); //返回大于等于x的最小的数的迭代器 核心操作
upper_bound(x); //返回大于x的最小的数的迭代器 不存在返回end()
4 遍历输出
1 使用迭代器遍历
//可以用auto替换set<int>::iterator
for(auto it = st.begin();it!= st.end();it++ )cout<<*it<<' ';
2 使用范围循环(c++11及更高版本)
//可以用auto 替换 int
for(const int &it :st)cout<<it<<' ';
for(auto it :st)cout<<it<<' ';//也是正确的
这种方式不需要你显示的使用迭代器,他会帮你自动处理
3 自由遍历
有些时候,我们并不想遍历输出所有的set集合,但是用迭代器的方法又不行,我们可以换个思路,用长度来遍历
set<int> st = {1,2,3,4,5};
int l = st.size(); //统计st的长度
auto it = st.begin(); //定义一个迭代器
for(int i = 0; i < l ; i++){
cout<<*it<<' ';
it++;
}
我们可以通过控制l来实现自由遍历