Set的底层是红黑树,红黑树是一种搜索二叉树。
Set的优势在于搜索速度上,搜索key值的时间赋值度是logn。
Set可以实现去重+排序的操作,已有的值不再重复插入,插入的数据自动排序
和其他数据结构一样set支出insert,erase,find等操作
set<int> s;
s.insert(1);
s.insert(2);
s.erase(2);
s.find(3);
访问set可以通过迭代器访问
auto si = s.begin();
while (si != s.end())
{
cout << *si;
si++;
}
对set的访问本质上是对一个搜索树的中序遍历。
set的特殊之处,当set的key是结构体时,可以传一个仿函数,定义比较key的大小规则
s.count()计算key是否存在,存在返回key个数,不存在返回0
set<int> s;
s.insert(1);
s.insert(4);
s.insert(5);
cout << s.count(3); // result:0
cout<<s.count(4); // result: 1
lower_bound()和upper_bound()返回值用作erase的迭代器参数
set<int> s;
for (int i = 0; i < 10; i++)
{
s.insert(i);
}
// 0,1,2,3,4,5,6,7,8,9,10
auto itlow = s.lower_bound(3);
auto itupper = s.upper_bound(4);
cout << *itlow; //3
cout << *itupper; //5
s.erase(itlow, itupper);
cout << endl;
auto si = s.begin();
while (si != s.end())
{
cout << *si;
si++;
}
cout << endl;
lower_bound,upper_bound表示删除3到4的范围包括3和4,所以*itlow>=3,itupper>4,itupper大于4的原因是erase迭代器是[ itlow, itupper).
当lower_bound和upper_bound传入一个不存在的值时。erase不会有任何改变。
s.insert(1);
s.insert(3);
itlow=s.low_bound(2);
itupper=s.upper_bound(2);
cout<<*itlow //3
cout<<*itupper //3
s.erase(itlow,itupper)// [3,3)
equal_range()返回一个结构体,结构体的两个成员变量分别是迭代器。
我们不妨将pair看成是c++返回两个值时的解决方法。
在set中equal_range可以看成lower_bound+upper_bound的结合体。
auto sr = s.equal_range(3);
cout << *sr.first; // 3
cout << *sr.second; // 4
在multiset中,equal_range可以实现去除操作
multiset允许重复的值比set
multiset<int> ms;
for (int i = 0; i < 10; i++)
{
ms.insert(i);
}
ms.insert(4);
ms.insert(4);
ms.insert(4);
auto ims = ms.equal_range(4);
cout << *ims.first;// 4
cout << *ims.second;// 5
ms.erase(ims.first, ims.second);
打印的结构是012356789;把4全都去掉。
当equal_range的值不存在时()会报错。
Map的底层也是搜索树,和set相比,他可以存两个值,key和value,set只存key,两者都是通过key来比较排序。
map<string,string> dict;
dict['apple']='taste';
图的初始化
pair<string, string> kv1("insert", "插入");
dict.insert(kv1);
dict.insert({ "string","字符串" }); // 隐式转换
dict.insert(make_pair("string", "排序"));// 匿名变量
图不是直接定义两个变量而是先定义pair结构体再插入进去。
注意,隐式转换的写法,C++11才支持双变量的隐式转换的写法。
当图的key相同时,插入不会覆盖也不会增加,所以图的key应该是唯一的。
map的[]
map<string,string> dict;
dict['apple']='taste';
dict['banana'];
当key为apple存在时,不作改变,当不存在时插入新的pair。
当key为banana存在时如上,当key不存在时,创建新的pair,value为用string的构造函数初始化。
map的访问
void test3()
{
map<string, int> dict;
dict.insert({ "apple", 4});
for (auto e : dict)
{
cout << e.first;
}
}