C++之map和set总结

Posted _BitterSweet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之map和set总结相关的知识,希望对你有一定的参考价值。

1.关联式容器

  • STL中比如:vector、list、deque、forward_list(C++11)等,这些都是序列式容器,因为底层都是线性序列的数据结构,里面存储的是元素本身
  • 关联式容器也是用来存储数据的,与序列式容器不同的是,里面存储的是<key,value>结构的键值对在数据检索时比序列式容器效率更高

2.键值对

  • 用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义

  • 在STL源码剖析中关于键值对的定义:

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)
 	{}
};

3.树形结构的关联式容器

  • 根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式
  • 容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。

3.1 set介绍

  • set是按照一定次序存储的容器
  • 底层结构是一个<k,v>结构,但是k和v是相同的数据
  • 创建set时只需要传入value,不需要传入k
  • set中不存放重复的数据
  • 不支持修改操作(容器中的元素总是const)
  • 迭代器遍历:数据是有序的,因为底层实际是二叉搜索树的中序遍历
  • 插入数据时,给定的迭代器位置只是一个建议,数据真正插入位置不一定是迭代器指向的位置,需要符合搜索树的基本性质
  • 删除数据时,可能会导致迭代器失效问题
  • 查找数据时,如果存在,返回数据的迭代器,如果失败,返回end迭代器
  • count接口计算要查找dd额数据个数,只可能返回0和1

3.1.1set的使用

  • set的模板参数列表
    在这里插入图片描述

  • set的构造
    在这里插入图片描述

  • set的迭代器
    在这里插入图片描述

  • set的容量
    在这里插入图片描述

  • set的修改操作
    在这里插入图片描述

3.2map介绍

  • map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素
  • 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:typedef pair value_type
  • 在内部,map中的元素总是按照键值key进行比较排序的
  • map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)
  • map支持下标访问符,即在[]中放入key,就可以找到与key对应的value

3.2.1 map的使用

  • map的模板参数

在这里插入图片描述

  • map的构造
    在这里插入图片描述

  • map的迭代器
    在这里插入图片描述

  • map中的容量与元素访问
    在这里插入图片描述
    这里有一个注意的点:当key不在map时,通过operator获取对应value会发生什么问题?

在这里插入图片描述
在这里插入图片描述
总结一句话就是,没有就插入,有就返回已有的value的引用

3.3multiset

在这里插入图片描述

  • multiset是按照特定顺序存储元素的容器,其中元素是可以重复的
  • 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除
  • 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序
  • multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列
  • multiset底层结构为二叉搜索树(红黑树)
  • 注意:
  • multiset中再底层中存储的是<value, value>的键值对
  • mtltiset的插入接口中只需要插入即可
  • 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
  • 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列(背后实际是BST的中序)
  • multiset中的元素不能修改
  • 在multiset中找某个元素,时间复杂度为O(log2N)
  • multiset的作用:可以对元素进行排序

3.4multimap

在这里插入图片描述

  • 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的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的

以上是关于C++之map和set总结的主要内容,如果未能解决你的问题,请参考以下文章

C++ set用法总结(整理)

C++之unordered_map和unordered_set以及哈希详解

C++之unordered_map和unordered_set以及哈希详解

C++从青铜到王者第二十篇:STL之setmapmultisetmultimap的初识

C++关联容器知识总结

ES6学习总结之Set和Map数据结构的理解