map和set的使用和实现(C++)
1.set类的定义:

T是底层关键字类型,后面两个模板参数可以不用传,set底层是⽤红⿊树实现,增删查效率是O(logN) ,迭代器遍历是⾛的搜索树的中序,所以是有序的。
1.1 set的构造

1.2 set的增删查:
以下是使用比较高频的函数接口:
函数名称 | 定义 |
insert() | 插入一个元素到set容器 |
erase() | 按键值或者迭代器删除一个或者一段元素 |
clear() | 清空set中所有元素 |
find() | 查找一个元素,并返回他的迭代器 |
count() | 统计键值的个数,结果只能是0或者1 |
代码演示:
1.3 multiset和set的差异
multiset和set的使⽤基本完全类似,主要区别点在于multiset⽀持值冗余,那insert/find/count/erase都围绕着⽀持值冗余有所差异,具体参看下⾯的样例代码理解。

2.map系列的使用
2.1 set的介绍
map的声明如下,Key就是map底层关键字的类型,T是map底层value的类型,set默认要求Key⽀持 ⼩于⽐较,如果不⽀持或者需要的话可以⾃⾏实现仿函数传给第⼆个模版参数,map底层存储数据的 内存是从空间配置器申请的。⼀般情况下,我们都不需要传后两个模版参数。map底层是⽤红⿊树实现,增删查改效率是 O(logN) ,迭代器遍历是⾛的中序,所以是按key有序顺序遍历的。
2.2 pair类型的介绍
map底层的红⿊树节点中的数据,使⽤pair<Key, T>存储键值对数据。
2.3map的构造
map的构造我们关注以下⼏个接⼝即可。map的⽀持正向和反向迭代遍历,遍历默认按key的升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛ 的中序;⽀持迭代器就意味着⽀持范围for,map⽀持修改value数据,不⽀持修改key数据,修改关键 字数据,破坏了底层搜索树的结构。

2.4 map增删查函数的使用
函数接口 | 使用说明 |
inser() | 插入一个还或者一段值 |
find() | 查找值 |
count() | 查找k值,返回值的k个数 |
erase() | 删除一个或者一段值 |
2.5 map的数据修改
前⾯我提到map⽀持修改mapped_type 数据,不⽀持修改key数据,修改关键字数据,破坏了底层搜 索树的结构。map第⼀个⽀持修改的⽅式时通过迭代器,迭代器遍历时或者find返回key所在的iterator修改,map 还有⼀个⾮常重要的修改接⼝operator[],但是operator[]不仅仅⽀持修改,还⽀持插⼊数据和查找数 据,所以他是⼀个多功能复合接⼝需要注意从内部实现⻆度,map这⾥把我们传统说的value值,给的是T类型,typedef为 mapped_type。⽽value_type是红⿊树结点中存储的pair键值对值。⽇常使⽤我们还是习惯将这⾥的 T映射值叫做value。
下面我们来着重讲一下find(),insert(),operator[]函数:
2.5.1 find():
iterator find (const key_type& k);
/查找k,返回k所在的迭代器,没有找到返回end(),如果找到了通过iterator可以修改key对应的
mapped_type值

2.5.2 insert():
pair<iterator,bool> insert (const value_type& val);
insert插⼊⼀个pair<key, T>对象1、如果key已经在map中,插⼊失败,则返回⼀个pair<iterator,bool>对象,返回pair对象first是key所在结点的迭代器,second是false2、如果key不在在map中,插⼊成功,则返回⼀个pair<iterator,bool>对象,返回pair对象first是新插⼊key所在结点的迭代器,second是true也就是说⽆论插⼊成功还是失败,返回pair<iterator,bool>对象的first都会指向key所在的迭代器那么也就意味着insert插⼊失败时充当了查找的功能,正是因为这⼀点,insert可以⽤来实现operator[]需要注意的是这⾥有两个pair,不要混淆了,⼀个是map底层红⿊树节点中存的pair<key, T>,另⼀个是insert返回值pair<iterator,bool>

2.5.3 operator[]
mapped_type& operator[] (const key_type& k);
1、如果k不在map中,insert会插⼊k和mapped_type默认值,同时[]返回结点中存储mapped_type值的引⽤,那么我们可以通过引⽤修改返映射值。所以[]具备了插⼊+修改功能2、如果k在map中,insert会插⼊失败,但是insert返回pair对象的first是指向key结点的迭代器,返回值同时[]返回结点中存储mapped_type值的引⽤,所以[]具备了查找+修改的功能
内在实现:
2.6 multimap和map的差异
multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么
insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如
find时,有多个key,返回中序第⼀个。其次就是multimap不⽀持[],因为⽀持key冗余,[]就只能⽀
持插⼊了,不能⽀持修改。
3.map和set的底层实现完整代码
mymap.h

myset.h
RBTree.h
期待下次见面!