STL的set和map都是基于红黑树实现的,和stack,queue都是基于deque一样,它们仅仅是调用了RBTree提供的接口函数,然后进行外层封装即可。
set是一种关联式容器,其特性如下:
第五点需要做一下说明。如果set中允许修改键值的话,那么首先需要删除该键,然后调节平衡,在插入修改后的键值,再调节平衡,如此一来,严重破坏了set的结构,导致iterator失效,不知道应该指向之前的位置,还是指向改变后的位置。所以STL中将set的迭代器设置成const,不允许修改迭代器的值。
map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。它的特性如下:
在map中,一个键对应一个值,其中键不允许重复,不允许修改,但是键对应的值是可以修改的,原因可以看上面set中的解释。
multimap和multiset就在map和set的基础上,使他们的键可以重复,除此之外基本等同。
根据key值快速查找记录,查找的复杂度基本是Log(N)
详情请移步:https://blog.csdn.net/terence1212/article/details/52487656
map对象是模板类,需要关键字和存储对象两个模板参数,例如下列构造函数:
map
数据的插入
//第一种:用insert函数插入pair数据
#include
//第二种:用insert函数插入value_type数据
#include
//第三种:用数组方式插入数据
#include
第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值。数据的遍历
//前向遍历前面已有,这里主要介绍利用反向迭代器
#include
数据的查找
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1
第二种:用find函数来定位数据出现位置,传入的参数是key,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
在这里需要提到的是begin()和end()两个成员,分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator. 注意:而vector中的end()是最后一个元素的后一个,有所区别。
#include
数据的删除
移除某个map中某个条目用erase(),该成员方法的定义如下:
iterator erase(iterator it); //通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(const Key&key); //通过关键字删除
clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());
#include
详情请移步:https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html
有关迭代器失效问题:
一般出现在循环erase中
序列性容器::(vector和list和deque)
erase迭代器不仅使所指向被删元素的迭代器失效,而且使被删元素之后的所有迭代器失效,所以不能使用erase(iter++)的方式,但是erase的返回值为下一个有效的迭代器。
所以正确方法为::
for( iter = c.begin(); iter != c.end(); )
iter = c.erase(iter);
关联性容器::(map和set比较常用)
erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器,
所以正确方法为::
for( iter = c.begin(); iter != c.end(); )
c.erase(iter++);
原因如下:对于该语句cout << *p++ << endl; 很多人错误地以为是先执行*p, 然后执行p++, 其实, 这是个天大的误解。 大家可以查一下*和++的执行顺序, 虽然*和++的优先级相同, 但此处采取的是右结合方式, 实际上先执行的是p++, 不过, p++的返回值是原来的p。
所以, 在m.erase(it++);中,it++先执行, 此时还没有erase, 程序自然不会崩溃. 当it++执行完后, 已经指向了下一个元素了, 但it++的返回值还是当前元素, 此时再删除它, 合情合理。
Tips:
其实对于list两种方式都可以正常工作。
参考链接:https://blog.csdn.net/aa838260772/article/details/39678187
https://blog.csdn.net/stpeace/article/details/46507451