C++:map和set重点解析

目录

1.关联式容器

[2.set 容器](#2.set 容器)

3.map

[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 - C++ 参考

上面的连接为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;

注意

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

3.map

map - C++ 参考

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;

介绍

  1. map 是关联容器,根据关键值 key 进行排序存储键值和 value 组合成的元素
  2. 使用 pair 将 key 和 value 绑定在一起,然后存储。
  3. map 支持下标访问,可以通过 key 访问 value,下面我们详细说
  4. 底层为红黑树,和 set 一样,通过 key 值排序,然后存储pair。
  5. 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;

}
相关推荐
ShineWinsu10 小时前
对于C++:auto_ptr、unique_ptr、shared_ptr的模拟实现
c++·面试·笔试·智能指针·unique_ptr·shared_ptr·auto_ptr
hsjiasb10 小时前
FreeRTOS学习(二十七)——任务栈与栈溢出检测
开发语言·stm32·学习·学习笔记·freertos
丰锋ff11 小时前
3.1 Qt事件之事件处理器
开发语言·qt
多弗朗皮卡丘11 小时前
C语言梦开始的地方7:函数
c语言·开发语言
月华路12 小时前
G1 垃圾回收:脏卡队列、记忆集与并发精化线程机制
java·开发语言
XLYcmy12 小时前
京东 算法实习一面 下+手撕
c++·python·llm·概率论·数据处理·训练·codebert
gugucoding12 小时前
47. 【Java】Java内存模型(JMM)与可见性
java·开发语言
m0_3807438712 小时前
从零调用 Claude 教程
开发语言·python·node.js
起床学FPGA13 小时前
AI回答问题之后,会自动跳到最下面的问题
开发语言·javascript·ecmascript
反转180度13 小时前
Qt 6 + C++17 实现 SFTP 批量部署:工业设备运维工具实战解析
运维·c++·qt