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;

}
相关推荐
冷雨夜中漫步4 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
半桔4 小时前
【IO多路转接】高并发服务器实战:Reactor 框架与 Epoll 机制的封装与设计逻辑
linux·运维·服务器·c++·io
HABuo5 小时前
【linux文件系统】磁盘结构&文件系统详谈
linux·运维·服务器·c语言·c++·ubuntu·centos
我在人间贩卖青春5 小时前
C++之多重继承
c++·多重继承
m0_736919106 小时前
C++代码风格检查工具
开发语言·c++·算法
2501_944934736 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
黎雁·泠崖7 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
2301_763472467 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
阿猿收手吧!8 小时前
【C++】std::promise原理与实战解析
c++
TechWJ8 小时前
PyPTO编程范式深度解读:让NPU开发像写Python一样简单
开发语言·python·cann·pypto