map和set_C++

一.map和set的使用

1.序列式容器和关联式容器

序列式容器是线性容器,两个位置存储的值一般没有紧密的关联联系,比如STL:string,vector,list,deque等

关联式容器是非线性容器,两个位置存储的值有紧密的关联联系,比如map,set,哈希表

二.set的使用

2.1 map和set底层是红黑树(平衡二叉搜索树)(logN)

<set> - C++ Reference

文档里面有介绍set的用法

2.2 set的声明(T是关键字类型)

cpp 复制代码
template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

2.3 set的构造和迭代器

set支持双向迭代器,默认是升序,底层是二叉搜索树中序遍历,所以是有序的

set的构造

cpp 复制代码
// empty (1) ⽆参默认构造
explicit set (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
// range (2) 迭代器区间构造
template <class InputIterator>
set (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& = allocator_type());
// copy (3) 拷⻉构造
set (const set& x);
// initializer list (5) initializer 列表构造
set (initializer_list<value_type> il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
// 迭代器是⼀个双向迭代器
iterator -> a bidirectional iterator to const value_type
// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend()

2.4 set的增删查

cpp 复制代码
Member types
key_type -> The first template parameter (T)
value_type -> The first template parameter (T)
// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator,bool> insert (const value_type& val);
// 列表插⼊,已经在容器中存在的值不会插⼊
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;

1.set的底层是平衡二叉搜索树,在删除的时候有直接删除比如:根节点3(迭代器失效),替代法删除:比如根节点12,那其实是13替代了原来12的位置(但是原来12的迭代器还是失效)

2.set.find(x)的时间复杂度是O(log(N)),是走高度次,算法库里面的find是O(N)

3.set.count(x)返回的是x元素的数量,set本身只有一个x,返回数量是与multiset对应,也就是可重复的升序集合

4.lower_bound和upper_bound

给定一个数x,lower_bound返回的是第一个>=x的迭代器,upper_bound返回的是>x的迭代器.

2.5multiset和set的差异

multiset和set的使⽤基本完全类似,主要区别点在于multiset⽀持值冗余,那么 insert/find/count/erase都围绕着⽀持值冗余有所差异

相⽐set不同的是,multiset是排序,但是不去重

在find查找的时候,找到的是中序(左根右)的第一个

例题1:https://leetcode.cn/problems/intersection-of-two-arrays

例题2:https://leetcode.cn/problems/c32eOV

三.map

map - C++ Reference

3.1 认识pair

pair - C++ Reference

1.the first是key,second是value

2.make_pair(key,value)就不用pair<T1,T2>(key,value);自动匹配类型

3.插入数据时只关注key,key相等就不会插入,与value无关.

4.the first是const类型的,不支持修改key但是value可以修改,second可以修改

5.比较是先比较first,再second

3.2map::insert

从文档里面可以看到返回的是一个pair<iterator,bool>,就是插入位置和查找功能

插入成功:pair<新插入值所在的迭代器,true成功插入>

插入失败:pair<与新插入值相等的值的迭代器,false插入失败>

3.3 map::operator[]

1.这里的[]不是vector等传统意义上的数组访问的[]

cpp 复制代码
// 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值的引⽤,所以[]具备了查找+修改的功能
pair<iterator, bool> ret = insert({ k, mapped_type() });
iterator it = ret.first;
return it->second;
}

2.operator底层是使用insert实现的,insert在失败的时候会变成查找功能

cpp 复制代码
//key不存在->插入{"insert",string()}
dict["insert"];//缺省

//key不存在->插入+修改
dict["left"]="左边"

//查找,确定key存在
cout<<dict["left"]<<endl;

//插入,因为sort不存在
cout<<dict["sort"]<<endl;

3.4multimap和map的差异

multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么 insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如 find时,有多个key,返回中序第⼀个。其次就是multimap不⽀持[],因为支持key冗余,[]就只能支持插⼊了,不能⽀持修改。

例题1:

例题2:https://leetcode.cn/problems/g5c51o?q=%E5%89%8Dk%E4%B8%AA

stable_sort,稳定排序,不改变相对位置

相关推荐
香蕉鼠片1 小时前
八股C++
开发语言·c++
AI视觉网奇1 小时前
python 截取矩形 缩放,旋转
开发语言·python·numpy
feng_you_ying_li1 小时前
C++之智能指针的介绍与实现
c++
清心歌1 小时前
ArrayList 深入解析
java
Yyyyy123jsjs1 小时前
轻松通过Python调用外汇api获取汇率数据
开发语言·python
墨^O^1 小时前
C++ Memory Order 完全指南:从 relaxed 到 seq_cst,深入理解无锁编程与 happens-before
linux·开发语言·c++·笔记·学习·算法·缓存
算.子2 小时前
【Spring AI 实战】五、RAG 核心原理:为什么需要检索增强生成?
java·人工智能·spring
阿正的梦工坊2 小时前
JavaScript 闭包:从入门到精通
开发语言·javascript·ecmascript