文章目录
- 1.什么是关联式容器
- 2.什么是键值对
- 3.树形结构的关联式容器
- 3.1set
- 3.1.2set的使用
- set的构造
- set的迭代器
- set的容量
- set的常用操作
- set的简单使用
- 3.2 map
- map的构造
- map的迭代器
- map的容量
- map的常用操作
- map的使用
- 3.3multiset
- 3.4 multimap
在介绍set和map容器前先了解什么是关联式容器和键值对
1.什么是关联式容器
在初始阶段我们所学的STL容器当中,像vector,list,stack,queue等都是序列式容器,因为在其底层为线性序列的数据结构,里面储存的元素本身。那么什么是关联式容器呢?
关联式容器也是用来存储数据的,与序列式式容器不同的是,其里面存储的是<key,value>结构的键值对,在数据检索时比序列式容器效率更高
2.什么是键值对
用来表示具有一一对应关系的一种结构,该结构种=中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。就像字典那样,一个英语单词对应着一个中文释义,那么我们可以是英语单词和中文释义是一一对应的关系,可以通过该单词找到与其对应的中文释义。
3.树形结构的关联式容器
在STL当中一共实现两种不同的结构管理式容器:树形结构与哈希结构。树型结构的关联式容器主要有4种:map、set、multimap、multiset。他们的共同特点:使用红黑树作为底层数据结构,容器中的元素是一个有序的序列。
3.1set
set
1.set是按照一定次序存储元素的容器
2.在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能再容器中修改(元素总是const),但是可以从容器中插入或是删除它们。
3.再内部,set中的元素总是按照内部比较对象(类型比较)所指示的特定严格排序准则进行排序。
4.set容器通过key访问单个元素的速度通常比unordered_set慢,但是它们允许根据顺序对子集进行直接迭代
5.set咋底层是用红黑树实现的
注意:
1.与map/multimap不同,map/multimap中存储的真正的键值对<key,value> ,set中只放value,但在底层实际放的是由<value,value> 构成的键值对
2.set中插入元素时,只需要插入value即可,不需要构造键值对
3.set中的元素不可重复(由此可以用set进行去重)
4.使用set的迭代器遍历set中的元素,可以得到有序的序列(底层为搜索二叉树(红黑树))
5.set中的元素默认按照小于来比较
6.set查找某个元素,时间复杂度为 l o g n log n logn
7.set中的元素不允许修改(如果修改了会改变红黑树的结构)
3.1.2set的使用
set的构造
分别为
构造空的set
迭代器构造
拷贝构造
set的迭代器
set的容量
set的常用操作
set的简单使用
#include <set>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v({ 2,3,1,5,6,3,2,4,5,1,9,0 });
//利用迭代器构造set
set<int> s(v.begin(), v.end());
for (auto& x : s)
cout << x << ' ';
//打印结果0 1 2 3 4 5 6 9
//可以看到set是具有去重操作的
cout << endl;
//set迭代器的使用
set<int>::iterator it = s.begin();
for (; it != s.end(); ++it)
cout << *it << ' ';
cout << endl;
//打印结果0 1 2 3 4 5 6 9
return 0;
}
3.2 map
map
key表示 键值对中key的类型(相当于字典中的英文单词)
value表示 键值对中value的类型 (相当于英文单词对应的中文)
compare:比较器的类型,map中的元素是按照key进行比较的,缺省情况下就是按照小于来比较,一般情况下(内置元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户直接写一个比较规则
Alloc:空间配置器
map的构造
map的迭代器
map的容量
map的常用操作
map的使用
#include <map>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<pair<string, string>> vp({{ "apple","苹果" },{ "yui", "结衣"} , { "man", "男人" } });
map<string, string> d(vp.begin(), vp.end());//构造map
for (auto& x : d)
cout << x.first << ":" << x.second << " ";
cout << endl;
//打印结果 apple:苹果 man:男人 yui:结衣 ,会根据key来进行排序
pair<string, string> p("cat", "猫");
d.insert(p);//map的插入
for (auto& x : d)
cout << x.first << ":" << x.second << " ";
cout << endl;
//打印结果:apple:苹果 cat:猫 man:男人 yui:结衣
d.erase("apple");//map的删除
for (auto& x : d)
cout << x.first << ":" << x.second << " ";
cout << endl;
//打印结果:cat:猫 man:男人 yui:结衣
//如果删除没有的key呢?
d.erase("apple");//apple已删除
for (auto& x : d)
cout << x.first << ":" << x.second << " ";
cout << endl;
//打印结果:cat:猫 man:男人 yui:结衣 //如果已经删除那么就也不会有什么影响
//下面介绍map最重要的功能:[]
//利用[],我们可以自由的对map进行插入和删除
d["haha"] = "哈哈";
for (auto& x : d)
cout << x.first << ":" << x.second << " ";
cout << endl;
//cat:猫 haha:哈哈 man:男人 yui:结衣
return 0;
}
结论:
1.map中的元素为键值对
2.map中的key是唯一的且不能修改
3.map利用迭代器遍历可以得到一个有序的序列
4.map支持[]的重载
3.3multiset
multiset
- multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
- 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成 的键值对,因此value本身就是key,key就是value,类型为T).
multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。- 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则 进行排序。
- multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
- multiset底层结构为二叉搜索树(红黑树)。
multiset和set最大的区别就是multiset的元素是可以重复的。multiset的头文件也在#include <set>
multiset的简单使用
#include <set>//multiset也在其中
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> v({ 2,3,1,5,6,3,2,4,5,1,9,0 });
//利用迭代器构造multiset
multiset<int> s(v.begin(), v.end());
for (auto& x : s)
cout << x << ' ';
//打印结果0 1 1 2 2 3 3 4 5 5 6 9
//可以看到multiset没有去重操作的
cout << endl;
//multiset迭代器的使用
multiset<int>::iterator it = s.begin();
for (; it != s.end(); ++it)
cout << *it << ' ';
cout << endl;
//打印结果0 1 1 2 2 3 3 4 5 5 6 9
cout<<s.count(1);//计算容器是对应元素的个数
//打印结果:2
return 0;
}
3.4 multimap
multimap
- Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
- 在multimap中,通常按照key排序和惟一地标识元素,而映射的value存储与key关联的内 容。key和value的类型可能不同,通过multimap内部的成员类型value_type组合在一起,value_type是组合key和value的键值对:
typedef pair<const Key, T> value_type;- 在内部,multimap中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对 key进行排序的。
- multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代 器直接遍历multimap中的元素可以得到关于key有序的序列。
- multimap在底层用二叉搜索树(红黑树)来实现。
同样multimap和map最大的区别就是允许key重复,同时取消了[]的重载(多个key限制了[]的重载)。