1.set的使用
1.1set的基本接口
*set和multiset参考⽂档
https://legacy.cplusplus.com/reference/set/
•
set的声明如下,T就是set底层关键字的类型
•
set默认要求T⽀持⼩于⽐较,如果不⽀持或者想按⾃⼰的需求⾛可以⾃⾏实现仿函数传给第⼆个模版参数
•
set底层存储数据的内存是从空间配置器申请的,如果需要可以⾃⼰实现内存池,传给第三个参
数。
•
⼀般情况下,我们都不需要传后两个模版参数。
•
set底层是⽤红⿊树实现,增删查效率是 ,迭代器遍历是⾛的搜索树的中序,所以是有序
的。
template<class T, class Compare = less<T>, class Alloc = allocator<T>> class set;
set的⽀持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛的中序;⽀持迭代器就意味着⽀持范围for,set的iterator和const_iterator都不⽀持迭代器修改数据,修改关键字数据,破坏了底层搜索树的结构。
// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find (const value_type& val);
// 查找val,返回Val的个数
size_type count (const value_type& val) const;
// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);
// 删除val,val不存在返回0,存在返回1
size_type erase (const value_type& val);
// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);
// 返回⼤于等val位置的迭代器
iterator lower_bound (const value_type& val) const;
// 返回⼤于val位置的迭代器
iterator upper_bound (const value_type& val) const;
*multiset和set的使用基本完全类似,但multiset支持值冗余。
1.相⽐set不同的是,multiset是排序,但是不去重
2.相⽐set不同的是,x可能会存在多个,find查找中序的第⼀个
3.相⽐set不同的是,count会返回x的实际个数
4.相⽐set不同的是,erase给值时会删除所有的x
2.8 349. 两个数组的交集 - ⼒扣(LeetCode)
142. 环形链表 II - ⼒扣(LeetCode)
std::set::insert 函数的返回值
std::set 容器的 insert 成员函数用于向集合中插入一个元素。
它的返回值是一个 std::pair<iterator, bool> 类型的对象,具体含义如下:
pair.first:一个迭代器,指向插入的元素或者是已经存在于集合中的等价元素。
pair.second:一个布尔值,如果插入成功(即集合中原本不存在该元素),
则为 true;如果插入失败(即集合中已经存在该元素),则为 false。
2.map的使用
2.1 map类的介绍
map的声明如下,Key就是map底层关键字的类型,T是map底层value的类型,set默认要求Key⽀持⼩于⽐较,如果不⽀持或者需要的话可以⾃⾏实现仿函数传给第⼆个模版参数,map底层存储数据的内存是从空间配置器申请的。⼀般情况下,我们都不需要传后两个模版参数。map底层是⽤红⿊树实现,增删查改效率是 O
(
logN
)
,迭代器遍历是⾛的中序,所以是按key有序顺序遍历的。
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> >
//map::allocator_type
> class map;
2.2 pair类型介绍
map底层的红⿊树节点中的数据,使⽤pair<Key, T>存储键值对数据。

2.3 map的构造
1.map的⽀持正向和反向迭代遍历,遍历默认按key的升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛的中序;⽀持迭代器就意味着⽀持范围for,map⽀持修改value数据,不⽀持修改key数据,修改关键字数据,破坏了底层搜索树的结构
2.
map增接⼝,插⼊的pair键值对数据,跟set所有不同,但是查和删的接⼝只⽤关键字key跟set是完全
类似的,不过find返回iterator,不仅仅可以确认key在不在,还找到key映射的value,同时通过迭代
还可以修改value
// 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
pair<iterator,bool> insert (const value_type& val);
// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find (const key_type& k);
// 查找k,返回k的个数
size_type count (const key_type& k) const;
// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);
// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;
*2.4 map operator[]数据修改
map第⼀个⽀持修改的⽅式时通过迭代器,迭代器遍历时或者find返回key所在的iterator修改,map还有⼀个⾮常重要的修改接⼝ope/rator[],但是operator[]不仅仅⽀持修改,还⽀持插⼊数据和查找数据,所以他是⼀个多功能复合接⼝
***建议看map/insert/[]的官方文档
***建议看map/insert/[]的官方文档
***建议看map/insert/[]的官方文档


// insert插⼊⼀个pair<key, T>对象
// 1、如果key已经在map中,插⼊失败,则返回⼀个pair<iterator,bool>对象,返回pair对象
first是key所在结点的迭代器,second是false
// 2、如果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构造遍历及增删查使用样例
2.6 map的迭代器和[]功能样例:
2.7 multimap和map的差异
multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么
insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如find时,有多个key,返回中序第⼀个。其次就是multimap不⽀持[],因为⽀持key冗余,[]就只能⽀持插⼊了,不能⽀持修改。
2.8 138. 随机链表的复制 - 力扣(LeetCode)
*2.9 692. 前K个高频单词 - 力扣(LeetCode)
1.数据量大时--建小堆(k个):依次读取数据,遍历比较,比堆顶数据大就替代堆顶值进堆(别建大堆,注意别搞返了)
2.少量数据(n个)--建大堆pop K次 或 直接排序,需仿函数控制降序;*优先级队列控制大小的逻辑是反的。
*注意:sort要求随机迭代器,而map是双向迭代器,所以若要用sort需把map中的先导到vector中;*并且快排不稳定,字典序会混乱。