【C++】set、map、multiset、multimap的用法简介


RB-tree是一种 平衡二叉搜索树自动排序效果很不错,所以标准的STL中set、map即以RB-tree作为底层的数据结构,set与map所开放的各种操作接口,RB-tree基本上都提供了,因此· set、map都只是 调用红黑树的方法对外层的一次封装而已。

一、STL::set特性
1)set的元素的键值就是实值,实值就是键值,即仅有一个值。

2)set不允许出现两个元素拥有相同的键值。

3)set所有的元素的键值都会自动被排序(默认升序)。

4)set iterators是一种constant itertors(相对于mutable iterators)。

5)set使用红黑树作为底层的数据结构。

下面是set一些常用的接口,对于set的底层实现不多说明,感兴趣的可以去看源码:
在这里插入图片描述

#include <set>
#include <iostream>
using namespace std;
int main()
{
	int arr[] = { 0,4,2,1,7,15,3,9,11 };//set会默认排序
	set<int> _s(arr,arr+sizeof(arr)/sizeof(arr[0]));
	cout << "Size: " << _s.size() << endl;//9
	cout << "2 Count:" << _s.count(2) << endl;//1
	_s.insert(2);//set不允许两个相同的键值
	cout << "Size: " << _s.size() << endl;//9
	cout << "Count:" << _s.count(2) << endl;//1
	_s.erase(4);
	cout << "Size: " << _s.size() << endl;//8
	cout << "4 Count:" << _s.count(4) << endl;//0
	set<int>::iterator it = _s.begin();//set的迭代器类型
	while (it != _s.end())
	{
		cout << *it << " ";//set会自动排序
		it++;
	}
	cout << endl;
	//使用find可以有效搜寻元素,但不是个好方法
	it = find(_s.begin(), _s.end(), 11);
	if (it != _s.end())
		cout << "found success." << endl;
	else
		cout << "find success" << endl;
	//面对关联式容器,应该使用find函数来搜寻元素,会比
	//STL的find更有效率,因为STL的find只是循序搜索
	it = _s.find(15);
	if (it == _s.end())
		cout << "not found" << endl;
	else
		cout << "find success." << endl;
	//*it = 10;  //set是不能被修改的
	int arr2[] = { 3,5,7,1,2,9,11,0 };
	set<int> _s1(arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
	it = _s1.find(7);
	_s1.erase(it,_s1.end());//删除it到end()之间的元素,默认会排序之后删除
	it = _s1.begin();
	while (it != _s1.end())
	{
		cout << *it << " ";//0 1 2 3 5
		it++;
	}
	cout << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

二、STL::map特性
1)map的所有元素都是pair,同时拥有键值key与实值value。

2)map不允许两个元素拥有相同的键值。

3)map的所有元素通过键值自动排序(默认升序)。

4)map的键值是不能被修改的,但是实值是可以被修改的。

5)map的使用红黑树作为底层的数据结构。

6)map重载了[],查询速度快。

下面是map一些常用的接口,对于set的底层实现不多说明,感兴趣的可以去看源码:
在这里插入图片描述

#include <map>
#include <iostream>
#include <string>
using namespace std;
int main()
{
	map<string, int> _m;//以string为键值,以int为实值
	_m[string("赵雷")] = 1;
	_m[string("李志")] = 2;
	_m[string("宋冬野")] = 3;
	pair<string, int> value(string("许巍"), 4);
	_m.insert(value);
	map<string, int>::iterator it = _m.begin();
	while (it != _m.end())//map会根据键值默认排序
	{
		cout << it->first << " " << it->second << endl;
		it++;
	}
	cout << _m[string("李志")] << endl;//2
	map<string, int>::iterator fd;
	//我们尽量还有关联式容器提供的find(),效率较高
	//STL提供的find()仅仅是循序搜索
	fd = _m.find(string("许巍"));
	if (fd == _m.end())
		cout << "not find." << endl;
	else
		cout << "find success." << endl;
	fd->second = 100;
	cout << fd->first << " " << fd->second << endl;
	//fd->first = "uuuuu";//不可以修改键值
	cout << "Size: " << _m.size() << endl;//4
	cout << _m.empty() << endl;
	_m.clear();//清空map
	cout << _m.empty()<< endl;
	system("pause");
	return 0;
}

在这里插入图片描述

三、STL::multiset特性

multiset的特性以及用法与set基本相同,两点差别在于:

1)multiset允许键值重复,它的插入动作调用的是insert_equal。

2)multiset的删除是删除所有值为key的元素。
#include <set>
using namespace std;
int main()
{
	int arr[] = { 2,4,3,0,5,6,1 };
	multiset<int> _ms(arr,arr + sizeof(arr) / sizeof(arr[0]));
	cout << "Size:" << _ms.size() << endl;
	multiset<int>::iterator it = _ms.begin();
	while (it != _ms.end())
	{
		cout << *it << " ";//自动排序
		++it;
	}
	cout << endl;
	_ms.insert(2);//调用的是insert_equal,而不是insert_unique
	cout << "Size:" << _ms.size() << endl;
	it = _ms.begin();
	while (it != _ms.end())
	{
		cout << *it << " ";//0 1 2 2 3 4 5 6
		++it;
	}
	cout << endl;
	_ms.erase(2);
	it = _ms.begin();
	while (it != _ms.end())
	{
		cout << *it << " ";//删除所有key为2的元素
		++it;
	}
	cout << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

STL::multimap特性
multimap的特性以及用法与map基本相同,差别如下:

1)允许重复键值的元素插入容器(使用了RB-Tree的insert_equal函数)2)键值key与元素value的映射关系是多对多的关系。

3)没有重载[]操作运算。

4)删除key即删除键值为key的所有元素。
#include <iostream>
#include <map>
using namespace std;
int main()
{
	std::multimap<char, int> mymultimap;
	mymultimap.insert(pair<char, int>('a', 10));
	mymultimap.insert(pair<char, int>('b', 20));
	mymultimap.insert(pair<char, int>('b', 30));
	mymultimap.insert(pair<char, int>('c', 40));
	mymultimap.insert(pair<char, int>('d', 50));
	mymultimap.insert(pair<char, int>('d', 60));
	mymultimap.insert(pair<char, int>('e', 70));
	mymultimap.insert(pair<char, int>('f', 80));
	multimap<char, int>::iterator it;
	for (it = mymultimap.begin(); it != mymultimap.end(); ++it)
		cout << (*it).first << " " << (*it).second << endl;
	mymultimap.erase('d'); //删除所有键值为d的元素                  
	it = mymultimap.find('e');
	mymultimap.erase(it, mymultimap.end()); //删除e到end()区间的所有元素
	for (it = mymultimap.begin(); it != mymultimap.end(); ++it)
		cout << (*it).first << " " << (*it).second << endl;
	system("pause");
	return 0;
}

在这里插入图片描述
参考博客:
https://blog.csdn.net/weixin_41413441/article/details/81603958

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农印象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值