一. set是一种关联式容器,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序,默认升序排列
二. 需要注意的是set中数元素的值不能直接被改变,在C++STL中,标准关联容器【如set, multiset, map, multimap】内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)
RB树的统计性能要优于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构
三. 另外,有下面两个地方值得关注:
1.map和set容器的插入和删除效率比其它序列式容器要高
2.在set中,查找使用的算法是基于二分算法的一种变体,明白这个道理后,就可以安心往里面放入元素了,不用担心速度问题
下面将介绍set容器的一些常见用法
1.向set中插入元素
st.insert(5);
st.emplace(6);
//这两种写法都可以,后一种在某些时候更加高效
2.删除set中的某个元素
st.erase(0); //删除set中的0
3.删除set中某一范围的元素
set<int>::iterator it1 = st.begin(), it2 = st.begin(); //先定义迭代器
advance(it1, 2), advance(it2, 5); //使迭代器移动位置
st.erase(it1, it2); //删除第3至第5个元素,也可以理解为下标[2,4]的元素
4.清空整个set
st.clear();
5.判断set是否为空
st.empty();
6.判断set中是否含有某个元素
st.count(4) //若存在4,返回1,不存在则返回0
7.在set中查找某一元素
set<int> st = {3, 4, 5, 7, 102, 34};
set<int>::iterator it = find(st.begin(), st.end(), 6);
if (it != st.end()) cout << "Yes";
else cout << "No";
//如果迭代器的返回值为st.end(),则表示查找失败,否则表示查找成功,此例子中明显查找不到,所以输出为NO
//下面这种写法也是可以的
set<int> st = {3, 4, 5, 7, 102, 34};
set<int>::iterator it = st.find(6);
if (it != st.end()) cout << "Yes";
else cout << "No";
8.交换两个set
st1.swap(st2);
//使用下面这种写法也可以
swap(st1, st2);
9.对set进行遍历
set<int> st = {1, 4, 2, 5, 3};
set<int>::iterator it; //首先定义迭代器
for (it = st.begin(); it != st.end(); it++) cout << *it << " "; //正序遍历
for (it = st.end(); it != st.begin();) cout << *(--it) << " "; //逆序遍历
//也可以利用反向迭代器进行逆序的遍历,方法如下:
set<int>::reverse_iterator it;
for (it = st.rbegin(); it != st.rend(); it++) cout << *it << " ";
10.将set2中不存在于set1中的元素并入set1中
set<int> st1 = {1, 4, 2, 5, 3}, st2 = {2, 6, 5, 7, 3, 8};
st1.merge(st2);
//完成后st1为1 2 3 4 5 6 7 8,st2为2 3 5
11.在set中二分查找第一个大于等于某个值的元素的迭代器
set<int> st1 = {1, 4, 2, 5, 3}, st2 = {2, 6, 5, 7, 3, 8};
set<int>::iterator it1 = st.lower_bound(4); //此时*it1为4
set<int>::iterator it2 = st2.lower_bound(4); //此时*it2为5
12.在set中二分查找第一个大于某个值的元素的迭代器
set<int> st1 = {1, 4, 2, 5, 3}, st2 = {2, 6, 5, 7, 3, 8};
set<int>::iterator it1 = st1.upper_bound(2); //此时*it1为3
set<int>::iterator it2 = st2.upper_bound(5); //此时*it2为6
13.在set中进行二分查找某个元素是否存在
set<int> st = {1, 3, 2, 5, 4};
int flag = binary_search(st.begin(), st.end(), 5); //flag为1表示存在,为0表示不存在,这里flag明显为1