目录
[1. set 和 map 的与其他类型的介绍对比](#1. set 和 map 的与其他类型的介绍对比)
[2. set 的系列介绍](#2. set 的系列介绍)
[2.1 set 和 multiset 的相关文献](#2.1 set 和 multiset 的相关文献)
[2.2 set 的初始化函数](#2.2 set 的初始化函数)
[2.3 set 的增删改函数](#2.3 set 的增删改函数)
[2.4 set 的其他函数](#2.4 set 的其他函数)
[2.5 set 和 multiset 的对比](#2.5 set 和 multiset 的对比)
[3. map 的系列介绍](#3. map 的系列介绍)
[3.1 map 和 multimap 的相关文献](#3.1 map 和 multimap 的相关文献)
[3.2 map 的初始化函数](#3.2 map 的初始化函数)
[3.3 map 的增删改函数](#3.3 map 的增删改函数)
[3.4 map 的其他函数](#3.4 map 的其他函数)
[3.5 map 的 operator\[\] 运算符重载](#3.5 map 的 operator[] 运算符重载)
[3.6 pair 类的介绍](#3.6 pair 类的介绍)
[3.7 map 和 multimap 的对比](#3.7 map 和 multimap 的对比)
1. set 和 map 的与其他类型的介绍对比
与之前的类型的对比 string vector list stack queue deque priority_queue 等的类型的,set 和 map 的类型与二叉搜索树关系更加相似,但他们的底层是以红黑树构成的,如果你现在还没有了解红黑树的话,那就先以比二叉搜索树更加牛逼的理解就可以。
在二叉搜索树章节中我们有稍微熟悉了二叉搜索树的底层,其中二叉搜索树中的结构有两个类型有关是 class K 和 class V , K 对应的是 _key 全部二叉搜索树的比较基准都是以 _key 为标准,V对应的是 _value 是附加的类型,set 就是两类型中有 _key 一个,map 就是有两个。
2. set 的系列介绍
2.1 set 和 multiset 的相关文献
set - C++ Reference multiset - C++ Reference
2.2 set 的初始化函数
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;
// 默认 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& alloc = allocator_type());
copy (3) // 拷贝构造
set (const set& x);
copy (1) // 等号运算算符重载
set& operator= (const set& x);
2.3 set 的增删改函数
cpp
// insert
single element (1) // 单个插入
pair<iterator,bool> insert (const value_type& val);
with hint (2) //
iterator insert (iterator position, const value_type& val);
range (3) // 区间插入
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// erase
(1) // 指定区间删除
void erase (iterator position);
(2) // 指定内容删除 // 看完 multiset 的话: 指定内容删除并且返回(size_t)n
size_type erase (const value_type& val);
(3) // 指定区间删除(要配合迭代器使用)
void erase (iterator first, iterator last);
// swap 交换
void swap (set& x);
// 清空
void clear();
2.4 set 的其他函数
cpp
// begin end rbegin rend
// begin 返回最小值的迭代器
iterator begin();
const_iterator begin() const;
// end 返回最大值的迭代器
iterator end();
const_iterator end() const;
// rbegin 返回最大值的迭代器
iterator rbegin();
const_iterator rbegin() const;
// rend 返回最小值的迭代器
iterator rend();
const_iterator rend() const;
// empty 判断是否为空
bool empty() const;
// size 返回已经节点有多少个
size_type size() const;
// count 检查是否有这个数,有就返回1,没有返回0
size_type count (const value_type& val) const;
// find 查找 给 val 返回地址
iterator find (const value_type& val) const;
// lower_bound 输入的数值返回地址,如果数值没有,查找比这个大的数值
iterator lower_bound (const value_type& val) const;
// upper_bound 输入的数值返回地址,如果数值没有,查找比这个小的数值
iterator upper_bound (const value_type& val) const;
// 两个对比 lower_bound 查找最大下限 upper_bound 查找最小上限
// equal_range 返回最大下限和最小上限 两个的结合
pair<iterator,iterator> equal_range (const value_type& val) const;
lower_bound 和 upper_bound 针对的是不同_ket 之间查找有效区间的;
equal_range 针对的是相同_ket 的有效区间 例如:1,2,2,2,3 就会把以一个2和最后一个3,有效区间 [2,3) 一起打包到pair<iterator,iterator>这个类中
cpp
void test_set1()
{
int arr[] = { 9,3,7,4,2,85,42,13,34 };
set<int> s(arr, arr + 9);
s.insert(10);
for (auto ch : s)
{
cout << ch << " ";
}
cout << endl;
s.erase(10);
for (auto ch : s)
{
cout << ch << " ";
}
cout << endl;
s.erase(s.begin());
for (auto ch : s)
{
cout << ch << " ";
}
cout << endl;
s.erase(s.begin(),s.end());
s.insert(10);
for (auto ch : s)
{
cout << ch << " ";
}
cout << endl;
return;
}

2.5 set 和 multiset 的对比
- 元素是否允许重复
set:不允许重复键值,容器内元素唯一;插入重复值会直接失败,不会新增元素。multiset:允许重复元素,可以存放多个相同的值,插入重复值成功。
cpp
set<int> s;
s.insert(1);
s.insert(1); // 无效,s 里只有一个1
multiset<int> ms;
ms.insert(1);
ms.insert(1); // 有效,ms 里有两个1
- 查找删除接口行为差异(高频考点)
find(val):返回第一个等于 val 的元素迭代器,两者行为一致。count(val)set:返回只能是 0 或 1multiset:返回有多少个等于 val 的元素
erase(val)(传值,不是迭代器!)set.erase(val):删除值为 val 的那一个元素multiset.erase(val):删除所有值等于 val 的元素
- 如果只想删掉 multiset 里其中一个:
cpp
auto it = ms.find(val);
if (it != ms.end()) ms.erase(it);
3. map 的系列介绍
3.1 map 和 multimap 的相关文献
map - C++ Reference multimap - C++ Reference
3.2 map 的初始化函数
cpp
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;
typedef pair<const Key, T> value_type;
cpp
// 构造函数
empty (1)
explicit map (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
range (2)
template <class InputIterator>
map (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
copy (3)
map (const map& x);
// 赋值运算符重载
copy (1)
map& operator= (const map& x);
3.3 map 的增删改函数
cpp
// insert 插入
single element (1) // 单个插入
pair<iterator,bool> insert (const value_type& val);
with hint (2) //
iterator insert (iterator position, const value_type& val);
range (3) // 指定区间插入
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
// erase 删除
(1) // 指定地址删除
void erase (iterator position);
(2) // 指定内容删除
size_type erase (const key_type& k);
(3) // 指定区间删除
void erase (iterator first, iterator last);
// swap 交换
void swap (map& x);
// clear 清空
void clear();
3.4 map 的其他函数
cpp
// begin end rbegin rend
// begin 返回最小值的迭代器
iterator begin();
const_iterator begin() const;
// end 返回最大值的迭代器
iterator end();
const_iterator end() const;
// rbegin 返回最大值的迭代器
iterator rbegin();
const_iterator rbegin() const;
// rend 返回最小值的迭代器
iterator rend();
const_iterator rend() const;
// empty 判断是否为空
bool empty() const;
// size 返回已经节点有多少个
size_type size() const;
// count 检查是否有这个数,有就返回1,没有返回0
size_type count (const key_type& val) const;
// find 查找 给 val 返回地址
iterator find (const key_type& val) const;
// lower_bound 输入的数值返回地址,如果数值没有,查找比这个大的数值
iterator lower_bound (const key_type& val) const;
// upper_bound 输入的数值返回地址,如果数值没有,查找比这个小的数值
iterator upper_bound (const key_type& val) const;
// 两个对比 lower_bound 查找最大下限 upper_bound 查找最小上限
// equal_range 返回最大下限和最小上限 两个的结合
pair<iterator,iterator> equal_range (const key_type& val) const;
3.5 map 的 operator\[\] 运算符重载
cpp
mapped_type& operator[] (const key_type& k);
map 的operator\[\] 运算符重相对于 vector 等的不一样(注意 multimap 没有这个运算符重载),相当于如果 k 在 map 中存在就返回对应地址,并且可以进行修改 map 中的 value 的(不是 ket),如果没有就会就会在这个区域进行插入新_key 空间,后面与前者的功能一致。
3.6 pair 类的介绍
cpp
template<class T1, class T2>
struct pair
{
T1 first; // 第一个成员
T2 second; // 第二个成员
};
pair 是一个拥有两个自定义类型模板结构体,在 map 常被用来当做 typedef pair<const Key, T> value_type; 头文件:#include <utility>
pair 类型还有内置的运算符重载
优先比较 first ,其次比较 second
cpp
template <class T1, class T2>
bool operator== (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return lhs.first==rhs.first && lhs.second==rhs.second; }
template <class T1, class T2>
bool operator!= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return !(lhs==rhs); }
template <class T1, class T2>
bool operator< (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return lhs.first<rhs.first || (!(rhs.first<lhs.first) && lhs.second<rhs.second); }
template <class T1, class T2>
bool operator<= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return !(rhs<lhs); }
template <class T1, class T2>
bool operator> (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return rhs<lhs; }
template <class T1, class T2>
bool operator>= (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
{ return !(lhs<rhs); }
pair 的使用
cpp
#include <iostream>
#include <map>
#include <utility>
#include <string>
using namespace std;
int main()
{
map<int, string> mp;
mp.insert(make_pair(1, "C++"));
mp.insert({2, "Java"});
mp[3] = "Python";
for(auto &p : mp)
{
cout << p.first << " : " << p.second << endl;
}
auto it = mp.find(2);
if(it != mp.end())
{
it->second = "GO";
}
return 0;
}
3.7 map 和 multimap 的对比
同理 map 和 multimap 都属于关联容器 ,底层都是红黑树(平衡二叉搜索树) ,元素按键key有序排列,迭代器遍历是升序;核心差别:map 键不允许重复,multimap 允许 key 重复。