> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。
> 目标:熟练掌握map和set容器。
> 毒鸡汤:得知坦然,失之淡然,争之必然,顺其自然。
> 望小伙伴们点赞👍收藏✨加关注哟💕💕
🌟前言
早期我们学习了顺序容器(vector,list...),像这块容器中的元素都是按照顺序存储的,学习起来相对来说比较轻松,这个轻松是相对的,在C++STL中我们还有一种容器为关联式容器,这种容器在底层的实现及其复杂,但是使用起来相对容易,也是苦了我们编译器。关联式容器比较有代表性的就是map和set,那它们又是使用呢,又有什么优点呢?带上这些问题进入今天的学习。
⭐主体
学习多态咱们按照下面的图解:
🌙关联式容器
容器分类:
- 序列式容器: 底层为线性序列的数据结构,里面存储的是元素本身,包含vector、list、deque、forward_list(C++11)等。
- 关联式容器: 里面存储的是结构的键值对,在数据检索时比序列式容器效率更高,包含set、map、unordered_set、unordered_map等。
注意: stack、queue和priority_queue属于容器适配器
关联式容器:
🌙键值对
概念分析:
用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。
应用场景:
现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。
代码分析:
template <class T1, class T2> struct pair { typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair() : first(T1()), second(T2()) {} pair(const T1& a, const T2& b) : first(a), second(b) {} };
C++的set
💫set的介绍
概念:
- set是按照一定次序存储元素的容器。
- 在set中,元素的value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
- 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
- set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
- set在底层是用二叉搜索树(红黑树)实现的。
注意:
- 与map/multimap不同,map/multimap中存储的是真正的键值对,set中只放value,但在底层实际存放的是由构成的键值对。
- set中插入元素时,只需要插入value即可,不需要构造键值对。
- set中的元素不可以重复(因此可以使用set进行去重)。
- 使用set的迭代器遍历set中的元素,可以得到有序序列
- set中的元素默认按照小于来比较
- set中查找某个元素,时间复杂度为:logN
💫set的使用
1.set的模板参数列表
分析:
- T: set中存放元素的类型,实际在底层存储的键值对
- Compare:比较方法,set中元素默认按照小于来比较(中序遍历为升序)
- Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理
2.set的构造函数
举个栗子:
int main() { set<int> set1; //空构造 int num[] = { 4,5,1,8,2,4,6,3 }; set<int> set2(num, num + sizeof(num) / sizeof(num[0])); //对于数组使用原生指针构造 set<int> set3(set2); //拷贝构造 // 范围for打印,从打印结果中可以看出:set可去重 for (auto& e : set3) cout << e << " "; cout << endl; }
运行结果:
3.set中迭代器相关函数
举个栗子:
int main() { set<int> s; //插入元素 s.insert(1); s.insert(4); s.insert(3); s.insert(3); s.insert(2); s.insert(2); s.insert(3); //遍历容器(正向迭代器) set<int>::iterator it = s.begin(); while (it != s.end()) { cout << *it << " "; it++; } cout << endl; //反向迭代器 set<int>::reverse_iterator rit = s.rbegin(); while (rit != s.rend()) { cout << *rit << " "; rit++; } cout << endl; }
运行结果:
4.set中常用的成员函数
举个栗子:
int main() { set<int> s; //插入元素(自动去重) s.insert(1); s.insert(4); s.insert(3); s.insert(3); s.insert(2); s.insert(2); s.insert(3); //遍历容器 for (auto e : s) { cout << e << " "; } cout << endl; //查找元素 set<int>::iterator pos = s.find(3); //删除元素 s.erase(pos);// 删除元素3 s.erase(4); //容器大小 cout << s.size() << endl; //清空容器 s.clear(); //容器判空 cout << s.empty() << endl; //交换两个容器的数据 set<int> tmp{ 10, 20, 30, 40 }; s.swap(tmp); //容器中值为2的元素个数 cout << s.count(2) << endl; cout << endl; }
【C++】map和set深度讲解(下) https://developer.aliyun.com/article/1565614