C++进阶:详细讲解容器set与map(pair、multiset、multimap)

这篇具有很好参考价值的文章主要介绍了C++进阶:详细讲解容器set与map(pair、multiset、multimap)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++进阶:详细讲解容器set与map(pair、multiset、multimap)

上次介绍了搜索二叉树:C++进阶:二叉搜索树介绍、模拟实现(递归迭代两版本)及其应用

为了介绍后面的AVLTree和红黑树,我们要进行一些铺垫,就是set与map的介绍啦



1.关联式容器与序列式容器

关联式容器和序列式容器是 C++ 中两种不同的容器类型

  1. 关联式容器:

    • 关联式容器主要包括 std::set, std::map, std::multiset, std::multimap 等。
    • 这些容器是基于键值对(<key, value>结构)的概念,通过键==(key)来唯一标识元素==。
    • 关联式容器内部使用二叉搜索树(通常是红黑树)或类似的数据结构,以保持元素的有序性。
    • 插入、删除、查找等操作的平均时间复杂度是 O(log n)。
  2. 序列式容器:

    • 序列式容器包括 std::vector, std::list, std::deque, std::array 等。
    • 这些容器是基于线性结构的,元素在容器中的位置是由插入的顺序决定的。
    • 插入、删除、查找等操作的平均时间复杂度因容器类型而异,但在最差情况下,可能达到 O(n)。

2.C++中的键值对——pair

在C++中,键值对是一种数据结构,通常用于表示关联关系

键值对由两部分组成:键(Key)和值(Value)。这种结构允许通过键来检索和关联对应的值,key代表键值,value表示与key对应的信息

2.1pair定义

std::pair 是C++标准库中提供的一个简单的键值对实现。它包含在 <utility> 头文件中。一个 std::pair 有两个公有成员:firstsecond,分别表示键和值==(first<= =>key ; second<= =>value)==

STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;
	T2 second;

	pair() //构造函数
	: first(T1()), second(T2())
	{}

	pair(const T1& a, const T2& b) //拷贝构造
	: first(a), second(b)
	{}
};

2.2pair的对象创建与访问

文档中的构造函数的介绍:

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. 默认构造函数:
  • pair();
  • 默认构造函数创建一个空的 std::pair 对象,不包含任何值。
  1. 拷贝构造函数:
  • template<class U, class V> pair (const pair<U,V>& pr);
  • 拷贝构造函数用于从另一个 std::pair 对象 pr 中复制键值对来构造一个新的 std::pair 对象。
  1. 初始化构造函数:
  • pair (const first_type& a, const second_type& b);
  • 初始化构造函数接受两个参数 ab,分别用于初始化 std::pair 对象的 firstsecond 成员变量。
void test_pair()
{
	pair<int, char> p1;//空参
	pair<int, char> p2(2, '2');

	pair<int, char> p3(p2);//拷贝构造

	cout << p1.first << " " << p1.second << endl;;
	cout << p2.first << " " << p2.second << endl;
	cout << p3.first << " " << p3.second << endl;
}

int main()
{
	test_pair();
	return 0;
}

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

2.3make_pair() 函数和使用{} -简化创建过程

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

void test_pair2()
{
	auto p4 = make_pair(2, 'c');//使用make_pair

	pair<int, char> p5 = { 3,'d' };//c++11后,使用{ }

	cout << p4.first << " " << p4.second << endl;
	cout << p5.first << " " << p5.second << endl;
}

int main()
{
	test_pair2();
	return 0;
}

我们能使用{}(初始化列表),是因为:构造函数匹配。如果使用花括号进行初始化,编译器会尝试匹配合适的构造函数。对于 pair,存在接受两个参数的构造函数,因此可以通过初始化列表直接构造键值对

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构


3. set容器

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. set是按照一定次序存储元素的容器

  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。

  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。

  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。

  5. set在底层是用二叉搜索树(红黑树)实现

3.1Constructs构造函数

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

void test_set1()
{
	set<int> s1;

	vector<int> v = { 1,2,3,4,5 };
	set<int> s2(v.begin(), v.end());//利用迭代区间

	set<int> s3 = s2;//拷贝构造
	for (auto e : s1)
	{
		cout << e << " ";
	}
	cout << endl;
	for (auto e : s2)
	{
		cout << e << " ";
	}
	cout << endl;	
	for (auto e : s3)
	{
		cout << e << " ";
	}
	cout << endl;
}

int main()
{
	test_set1();
	return 0;
}

3.2Iterator 迭代器

函数声明 功能
iterator begin(); 返回指向set开头的迭代器
iterator end(); 返回指向set最后一个元素后面的迭代器
const_iterator cbegin() const; 返回指向set开头的const迭代器
const_iterator cend() const; 返回指向set最后一个元素后面的const迭代器
reverse_iterator rbegin(); 返回指向set最后一个元素的反向迭代器
reverse_iterator rend(); 返回指向set第一个元素前面的反向迭代器
const_reverse_iterator crbegin() const; 返回指向set最后一个元素的反向const迭代器
const_reverse_iterator crend() const; 返回指向set第一个元素前面的反向const迭代器

3.3 插入、删除、查找、count

3.3.1 insert()插入

声明:pair<iterator, bool> insert(const value_type& val);

  • 插入元素到 set 中。
  • 如果插入成功,返回一个迭代器指向插入的位置和 true
  • 如果元素已经存在,返回一个迭代器指向已存在的元素和 false
  • 返回一个 pair 对象,包含插入的迭代器和插入是否成功的标志。

3.3.2 erase() 删除

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

函数声明 功能介绍 返回值
iterator erase(iterator position); 删除指定位置的元素,并返回指向被删除元素之后元素的迭代器。 指向被删除元素之后元素的迭代器。
size_type erase(const key_type& k); 删除 set 中所有等于指定键值的元素。返回删除的元素个数。 删除的元素个数。
iterator erase(iterator first, iterator last); 删除区间 [first, last) 中的所有元素,并返回最后一个被删除元素之后的迭代器。 指向被删除元素之后元素的迭代器。

3.3.3 find()查找

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

find 函数用于在 set 中查找指定键值的元素,并返回指向该元素的迭代器。如果元素不存在,则返回 end()

3.3.4 count()函数

声明:size_type count (const key_type& k) const;

count 函数用于统计 set 中与指定键值相等的元素个数。由于 set 中元素的键值是唯一的,因此该函数的返回值要么是 0(元素不存在),要么是 1(元素存在)

void test_set2()
{
	// 排序+去重
	set<int> s;
	s.insert(5);
	s.insert(1);
	s.insert(6);
	s.insert(3);
	s.insert(5);
	s.insert(1);

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	set<int>::iterator pos = s.find(5);//找到5就删除
	if (pos != s.end())
	{
		cout << "找到了" << endl;
		s.erase(pos);
	}

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	if (s.count(1))
	{
		cout << "1在" << endl;
	}
	else
	{
		cout << "1不在" << endl;
	}
}

int main()
{
	test_set2();
	return 0;
}

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构


4.容器 multiset

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。

  2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。

  3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。

  4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。

  5. multiset底层结构为二叉搜索树(红黑树)

注意:

  1. multiset中再底层中存储的是<value, value>的键值对

  2. mtltiset的插入接口中只需要插入即可

  3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的

  4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列

  5. multiset中的元素不能修改

  6. 在multiset中找某个元素,时间复杂度为 O ( l o g 2 N ) O(log_2 N) O(log2N)

  7. multiset的作用:可以对元素进行排序

multiset 是 C++ 标准库中的关联式容器之一,属于有序容器。与 set 不同的是,multiset 允许键值重复,即可以包含相同键值的多个元素。

  • 允许重复键值: multiset 允许容器中存在相同的键值,因此可以包含多个相同键值的元素。

  • 有序性: 与 set 类似,multiset 也维护元素的有序性,根据键值进行排序。

  • 当需要允许键值重复,并且希望保持元素有序时,可以选择使用 multiset

5.map 容器

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。

  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:

  3. 在内部,map中的元素总是按照键值key进行比较排序的。

  4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。

  5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。

  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

5.1map 模板参数说明

key: 键值对中key的类型

T: 键值对中value的类型

Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器

5.2 对象的创建

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

void testmap1()
{
	map<string, string> m1;//空的
	map<string, string> m2(m1);//拷贝构造
}

5.3 迭代器,insert,find ,[]重载

5.3.1 迭代器

下面是关于 multiset 中成员函数 begin(), end(), cbegin(), cend(), rbegin(), rend(), crbegin(), 和 crend() 的函数声明和功能介绍:

函数声明 功能介绍
iterator begin(); 返回 multiset 中首元素的位置的迭代器。
iterator end(); 返回 multiset 中最后一个元素后面的位置的迭代器。
const_iterator cbegin() const; 返回 multiset 中首元素的位置的 const 迭代器,不能修改所指向的元素。
const_iterator cend() const; 返回 multiset 中最后一个元素后面的位置的 const 迭代器,不能修改所指向的元素。
reverse_iterator rbegin(); 返回指向 multiset 中第一个元素的反向迭代器,即 end()
reverse_iterator rend(); 返回指向 multiset 中最后一个元素下一个位置的反向迭代器,即 rbegin()
const_reverse_iterator crbegin() const; 返回指向 multiset 中第一个元素的反向 const 迭代器,不能修改所指向的元素。
const_reverse_iterator crend() const; 返回指向 multiset 中最后一个元素下一个位置的反向 const 迭代器,不能修改所指向的元素。

5.3.2 insert() 函数

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

void testmap2()
{
	map<string, string> m1;//空的
	
	m1.insert(pair<string, string>("sort", "排序"));//匿名对象
	m1.insert(make_pair("apple", "苹果"));//使用make_pair函数
	m1.insert({ "apple", "苹果" });// C++11 多参数隐式类型转换(构造函数支持)
}

5.3.3 find() 函数

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

map 中,find 函数用于查找指定键的元素,并返回指向该元素的迭代器。如果找到了指定的键,则返回指向该键值对的迭代器;如果未找到,则返回指向 map 末尾的迭代器。

函数声明 功能介绍
iterator find(const key_type& k); 查找键值为 k 的元素,并返回一个指向该元素的迭代器。如果 k 存在于 map 中,则返回指向该元素的迭代器;如果不存在,则返回指向 map 末尾的迭代器。
const_iterator find(const key_type& k) const; 在常量 map 中查找键值为 k 的元素,并返回一个指向该元素的迭代器。如果 k 存在于 map 中,则返回指向该元素的迭代器;如果不存在,则返回指向 map 末尾的迭代器。

5.3.4 []

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. 读取元素:当使用 [] 运算符时

    • 如果指定的键存在于 map 中,则返回与该键关联的值
    • 如果不存在,则会插入一个新的键值对,键为指定的键,值为默认构造的对应值类型的默认值,并返回该默认值的引用
  2. 插入元素:当使用 [] 运算符向 map 中插入元素时

    • 如果指定的键不存在,则会创建一个新的键值对,键为指定的键,值为指定的值,并返回该值的引用
    • 如果键已经存在,则直接返回对应的值的引用
void testmap3()
{
	map<string, string> m1;//空的

	m1.insert(pair<string, string>("sort", "排序"));//匿名对象
	m1.insert(make_pair("apple", "苹果"));//使用make_pair函数
	m1.insert({ "left", "左边" });// C++11 多参数隐式类型转换(构造函数支持)
	for (auto& kv : m1)
	{
		cout << kv.first << ":" << kv.second << " ";
	}
	cout << endl;

	m1["right"];//这是插入一个right(key)
	m1["apple"] = "青苹果";//这里是进行修改

	for (auto& kv : m1)
	{
		cout << kv.first << ":" << kv.second << " ";
	}
	cout << endl;
}

int main()
{
	testmap3();
	return 0;
}

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构


6.容器 multimap

C++进阶:详细讲解容器set与map(pair、multiset、multimap),c++学习,c++,java,开发语言,linux,c语言,算法,数据结构

  1. multiset是按照特定顺序存储元素的容器,其中元素是可以重复的

  2. 在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。

  3. 在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。

  4. multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。

  5. multiset底层结构为二叉搜索树(红黑树)

注意

  1. multiset中再底层中存储的是<value, value>的键值对

  2. mtltiset的插入接口中只需要插入即可

  3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的

  4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列

  5. multiset中的元素不能修改

  6. 在multiset中找某个元素,时间复杂度为 O ( l o g 2 N ) O(log_2 N) O(log2N)

  7. multiset的作用:可以对元素进行排序


这次就到这里啦!!!感谢大家支持!!!文章来源地址https://www.toymoban.com/news/detail-848430.html

到了这里,关于C++进阶:详细讲解容器set与map(pair、multiset、multimap)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高阶数据结构】map和set的介绍和使用 {关联式容器;键值对;map和set;multimap和multiset;OJ练习}

    关联式容器和序列式容器是C++ STL中的两种不同类型的容器。 关联式容器是基于键值对的容器 ,其中每个元素都有一个唯一的键值,可以通过键值来访问元素。关联式容器包括set、multiset、map和multimap。 序列式容器是基于元素序列的容器 ,其中元素按照一定的顺序排列,可以

    2024年02月11日
    浏览(33)
  • C++:stl中set(multiset)和map(multimap)的介绍和使用

    本文主要从概念、常用接口和使用方法方面介绍set(multiset)和map(multimap)。 目录 一、概念介绍 1.关联式容器 2.键值对 3. 树形结构的关联式容器 二、set和multiset 1.set的介绍 2.set使用 1. set模板参数列表 2. set构造 3. set迭代器 4. set容量 5. set修改操作 6.set使用举例 3.multiset介绍 4.mul

    2024年02月08日
    浏览(30)
  • 【C++】map/multimap/set/multiset的经典oj例题 [ 盘点&全面解析 ] (28)

    前言 大家好吖,欢迎来到 YY 滴C++系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初学者易

    2024年02月04日
    浏览(33)
  • 详解map、set、multimap、multiset的使用

    ✍ 作者 : 阿润菜菜 📖 专栏 : C++ map、set、multimap、multiset是C++ STL中的四种关联容器,它们内部都使用了红黑树这种高效的平衡检索二叉树来存储数据 。它们的区别和用法如下: map是一种 键值对 容器,它可以根据键来快速查找、插入和删除值,它的键是唯一的,不能重复

    2024年02月03日
    浏览(21)
  • ⚡【C++要笑着学】(31) 映射类:map 类 | pair 类型 (value_type) | map 的插入和遍历 | map 的 operator[] | multimap 类

        C++ 表情包趣味教程 👉 《C++要笑着学》 💭 写在前面: 本章我们继续讲解 STL,讲解 STL 的 map 类。我们将详细介绍 map 类的基础概念,包括 pair 类型(value_type)的应用和插入元素的方法。随后,我们将深入研究 Map 的遍历方式以及统计元素出现次数的几种方式。最后我

    2024年02月03日
    浏览(33)
  • 【C++】map/multimap容器

    2024年02月10日
    浏览(28)
  • 【C++ STL之map,set,pair详解】

    在C++的STL(Standard Template Library)中,map是一个非常有用的关联容器。它提供了一种键-值对的数据结构,其中的元素按照键的顺序进行排序,并且每个键是唯一的。本文将详细介绍C++ STL中map的使用方法和一些常见操作。 (1)头文件 (2)初始化方法 可以使用以下方式声明和

    2024年02月12日
    浏览(23)
  • Google 开源库Guava详解(集合工具类)—Maps、Multisets、Multimaps

    Maps有许多很酷的实用程序,值得单独解释。 Maps.uniqueIndex(Iterable,Function)解决了一个常见的情况,即有一堆对象,每个对象都有一些唯一的属性,并希望能够根据该属性查找这些对象。 假设我们有一堆字符串,我们知道它们有唯一的长度,我们希望能够查找具有特定长度

    2024年02月03日
    浏览(30)
  • 【C++进阶】pair容器

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 假设我想打包两种数据,第一个是学生的姓名,第二个是学生的学号,我们就可以写出

    2024年02月07日
    浏览(55)
  • 【045】C++中map和multimap容器全面解析:深入学习,轻松掌握

    在C++中,map和multimap容器是非常重要的数据结构,它们提供了一种键值对的映射关系,可以高效地组织和访问数据。map容器中的每个元素都包含一个键和一个值,而multimap容器允许键重复。 这两种容器在实际项目中广泛应用,特别适合需要快速查找和插入元素的场景。其底层

    2024年01月17日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包