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;

}
相关推荐
No0d1es1 天前
2025年12月 GESP CCF编程能力等级认证Python一级真题
开发语言·python·青少年编程·gesp·ccf
a努力。1 天前
中国电网Java面试被问:分布式缓存的缓存穿透解决方案
java·开发语言·分布式·缓存·postgresql·面试·linq
草莓熊Lotso1 天前
脉脉独家【AI创作者xAMA】| 开启智能创作新时代
android·java·开发语言·c++·人工智能·脉脉
moxiaoran57531 天前
Java设计模式的运用
java·开发语言·设计模式
源代码•宸1 天前
Leetcode—1339. 分裂二叉树的最大乘积【中等】
开发语言·后端·算法·leetcode·golang·dfs
Chasing Aurora1 天前
C++后端开发之旅(一)
java·开发语言·c++
码农水水1 天前
美团Java后端Java面试被问:Kafka的零拷贝技术和PageCache优化
java·开发语言·后端·缓存·面试·kafka·状态模式
hz_zhangrl1 天前
CCF-GESP 等级考试 2025年12月认证C++六级真题解析
c++·算法·青少年编程·程序设计·gesp·c++六级·gesp2025年12月
bkspiderx1 天前
C++多态:面向对象编程的核心机制
c++·多态·函数重载·回调函数·运算符重载·虚函数·纯虚函数