目录
map、set底层都使用平衡搜索树(即红黑树),容器中的元素是一个有序的序列。
set概念
1.set和map都是关联式容器:
与序列式容器(vector、list、deque)不同的是,关联式容器也是用来存储数据的,其里面存储的是结构的键值对(键值对是用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息,例如找到中文即可一一对应英文),在数据检索时比序列式容器效率更高。
2.在set中,元素的value就是key,是一个key模型(类型为模板参数T),每个value必须是唯一的(默认去重)。 set中的元素不能在容器中修改(否则会破坏树的结构),但是可以从容器中插入或删除它们。set是去重+排序(按照中序遍历是有序的)
3.模板中传compare仿函数,是方便控制“比较”规则,less默认用T对象本身比较大小(调用T的operator<),
如果T是自定义类型,默认不支持比较大小;或者需要指针解应用里面的内容来进行比较,可以自己写仿函数
set基本使用
set.insert
在set中插入元素x,实际插入的是<x, x>,构成的键值对,如果插入成功,返回pair中<该元素在set中的位置,true>;如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false>
set.erase
直接使用erase删除不存在的值,不会报错
![](https://img-blog.csdnimg.cn/6651d08aebc84226ae15d00bd244c409.png)
erase配合set中find来删除不存在的值,会导致程序崩溃
![](https://img-blog.csdnimg.cn/01ebe0919fa446f29be0b3580b6524dc.png)
原因在于find找不到对应值,返回end位置,erase删除了end位置。
正确做法是应该判断pos != end()再进行删除
set和multiset的区别在于:
multiset中的find查找的是所有重复元素,返回的是中序的第一个重复元素;
multiset直接erase删除的是所有重复元素,multiset中的find+erase是删除一个元素
count
count并不是为set准备的,而是为multiset(允许键值冗余)准备的,用于查找重复元素个数
但是实际也可以用count查找在不在,返回bool
lower_bound/upper_bound
lower_bound返回的是大于等于这个值的位置
upper_bound是开区间,返回大于这个值的位置(给60返回70)
void test_set1()
{
std::set<int> myset;
std::set<int>::iterator itlow, itup;
for (int i = 1; i < 10; i++)
myset.insert(i * 10); // 10 20 30 40 50 60 70 80 90
itlow = myset.lower_bound(35); // ^
itup = myset.upper_bound(60);
cout << *itlow <<" " << *itup << endl;//40 70
}
equal_range:是一种二分查找算法,试图在已排序的[first,last)中寻找value
equal_range结构是pair键值对,给的是一段范围区间
左区间存在pair.first中,右区间存在pair.second中,区间范围是 first <= val < second (左闭右开