1、标准库提供8个关联容器
前部分底层数据结构是红黑树,后部分底层数据结构是哈希表,具体细节见《STL源码剖析》
2、容器概述
容器列表初始化举例
map的列表初始化中每个pair都需要用{}括起来
可提供自己定义的操作来的代替关键字上的<关键字
无论我们怎么定义,都需具备以下性质
使用关键字类型的比较函数
如果容器的关键字是我们自己定义的类,那么我们在定义容器时除了要指定关键字类型外,还需要指定比较操作类型
比如
pair类型
pair定义在头文件utility中,它有2个数据成员,都是public类型的,分别命名为first和second
map的元素类型就是pair
pair上的操作
3、关联容器操作
关联容器额外类型别名
关联容器insert操作
检测insert返回值
对于不包含重复关键字的容器,添加单一元素的insert和emplace会返回一个pair,pair的first成员是一个迭代器,指向具有给定关键字的迭代器,second是一个bool类型,指出元素是插入成功还是已经存在于容器中
map<int, int> m;
auto ret = m.insert({1,1});
cout<<ret.second<<endl; //输出1
ret = m.insert({1,2});
cout<<ret.second<<endl; //输出0
删除元素
map的下标操作
由于使用下标操作可能导插入一个新的元素,所以之能对非const的map使用下标操作
使用下标操作的返回值
下标操作的返回值是左值,是mapped_type对象,可以进行修改
而使用迭代器进行解引用得到的是pair,是value_type对象
访问元素
find操作和下标操作
find仅仅是知道关键字是否在map中,不会进行插入
下标操作当关键字不在map中时,会自动进行插入
multiset和multimap查找元素
multiset和multimap中相同关键字是相邻存储的,调用find会返回第一个关键字的迭代器
如果想遍历某一关键字,可以先用count计算出关键字有多少个,再依据得到的个数用find得到的迭代器执行递增来进行遍历
除此之外,还可以用lower_bound和upper_bound实现(若元素不在容器中,则lower_bound和upper_bound会返回相等的迭代器,都指向给定关键字的插入点),此外需要注意的是upper_bound是尾后迭代器
equal_range函数
除上面2种方法外,还可用equal_range来查找关键字,equal_range返回一个pair,first保存的迭代器和lower_bound保存的一样,second保存的迭代器和upper_bound保存的一样
4、无序容器
无序容器管理操作
无序容器对关键字类型的操作
默认情况下,无序容器使用关键字类型的==运算符比较元素,若用自己的类型来作为关键字类型时,需要提供函数来代替==运算符和哈希值计算函数
若我们的类定义了==运算符,则可以只重载哈希函数
end