目录
[2.set 容器](#2.set 容器)
[4. multiset 容器](#4. multiset 容器)
1.关联式容器
序列式容器:queue、vector、list,按照插入顺序存储数据,查找数据需要遍历时间复杂度为O(n)
今天说有序关联容器 map和set,是关联式容器的一种;map和set的底层是红黑树。而红黑树是基于搜索二叉树改进的。
关联式容器:数据之间有关联,之间符合一定的规则;便于查找。存储的不再是单一的元素,而是<key,value>的键值对,查找比较方便,时间复杂度为O(logN)量级。
关联式容器之间的规则依靠关键字(key)建立了逻辑关系,相比于序列式容器更加高效。
键值对 可以理解为一个结构有两个值 一个是key一个value,每个key和value一 一对应;C++中一般使用pair来表示键值对,
pair
cpp
template <class T1, class T2> struct pair;

first 为 key second 为 value
2.set 容器
上面的连接为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 存储的数据就是 key,按照 key 建立有序联系
- set 的 key 和 value 就是同一个模板参数,访问 set 的 value 就是访问 key 值。暂时理解为 set 中只存储一份 key (打个断点不确定)。
- set 不允许修改 key 值,因为会破坏以 key 值建立的逻辑关系;由于 value 和 key 是同一个值,因此 二着均不可修改。
- 不存储重复的值,底层为搜索二叉树,具有排序和去重的功能
- set 的 find 函数时间复杂度为 Olog(N),犹豫序列式容器的O(N)
3.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;


介绍
- map 是关联容器,根据关键值 key 进行排序存储键值和 value 组合成的元素
- 使用 pair 将 key 和 value 绑定在一起,然后存储。
- map 支持下标访问,可以通过 key 访问 value,下面我们详细说
- 底层为红黑树,和 set 一样,通过 key 值排序,然后存储pair。
- key 值是无法修改的,但是 value 是可以修改的
map的插入
cpp
map<string, string> mp;
pair<string, string> kv = { "string","字符串" };
mp.insert(kv);
// C++11 多参数的构造函数隐式类型转换
mp.insert({"insert","插入"});
// C++98
mp.insert(make_pair( "erase","消除"));
// 强制类型转换
mp.insert(pair<string, string>("sort", "排序"));

其他函数比较简单,这里说一下让 operator[ ]函数


operator[ ]的使用等价于 下面的结构
cpp
(*((this->insert(make_pair(k,mapped_type()))).first)).second
下面的这段程序调用的是insert函数,
cpp
(this->insert(make_pair(k,mapped_type()))
insert的返回值为 pair<iterator,bool>,相当于相面的程序
cpp
(*(pair<iterator,bool>.first)).second
cpp
(*(iterator).second
然后我们在看看迭代器

second 就是 value值,所以 [ ] 可以访问对应 key 的 value。并且具有插入的作用,看下述的程序
cpp
void testmap3()
{
map<string, string> dict;
dict.insert(make_pair("string", "字符串"));
dict.insert(make_pair("sort", "排序"));
dict.insert(make_pair("insert", "插入"));
dict["erase"]; //插入数据;
dict["erase"] = "删除"; // 修改
cout << dict["erase"] << endl;
dict["erase"] = "xxxxxx"; //修改
dict["map"] = "映射、地图"; //插入+修改
for (const auto& kv : dict)
{
cout << kv.first << ":" << kv.second << endl;
}
}
4. multiset 容器
cpp
template < class T, // multiset::key_type/value_type
class Compare = less<T>, // multiset::key_compare/value_compare
class Alloc = allocator<T> > // multiset::allocator_type
> class multiset;
介绍 性质和set一样。但是不同的是可以存储多个相同key值。
测试如下,主要注意 count函数,返回相同 key 值出现的数量; equal_range函数,返回pair,一个等于值一个大于其的值,可以用于删除等于key的全部的值,lower_bound函数返回大于等于这个值得迭代器,upper_bound返回大于这个值得迭代器。

cpp
void testset2()
{
multiset<int> ms;
int arr[] = { 1,2,88,8,7,3,5,9674,9,148,51,5,589,451,561,5,84,6,66,161,8 };
for (const auto& e : arr)
{
ms.insert(e);
}
cout << ms.size() << endl;
for (auto& e : ms)
{
cout << e << " ";
}
cout << endl;
cout << "8:"<<ms.count(8) << endl;
cout << "5:" << ms.count(5) << endl;
auto ret = ms.equal_range(5);
cout << *(ret.first) << endl;
cout << *(ret.second) << endl;
ms.erase(ret.first, ret.second);
for (auto& e : ms)
{
cout << e << " ";
}
cout << endl;
}