2.8 C++STL set/multiset容器详解
2.8.1 引入
set/multiset容器概念
set和multiset是一个集合容器,其中set所包含的元素是唯一的,集合中的元素按一定的顺序自动排列。set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。在n个数中查找目标数的效率是 log 2 n。
set容器中不允许重复元素,multiset允许重复元素。
只提供Insert方法初始化,如下图。

set常用API见set 常用API_qq_41050821的博客-CSDN博客
2.8.2 代码示例
#include<iostream>
#include<set>
using namespace std;
//仿函数
class mycompare
{
public:
bool operator()(int v1,int v2)const
{
return v1 > v2;
}
//这里要加上const ,原视频vs2019会报错,详情见 https://www.cnblogs.com/qrlozte/p/4437418.html
};
//初始化
void text01()
{
set<int> s1;//自动进行排序,默认从小到大。
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
s1.insert(9);
for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//赋值操作
set<int> s2;
s2 = s1;
//删除操作
s1.erase(s1.begin());
s1.erase(7);
for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//如何改变默认排序,从大到小。//先序遍历,中序遍历,后序遍历。
//借助仿函数
mycompare com;
com(20, 30);
set<int, mycompare> s3;//自动进行排序,默认从小到大。
s3.insert(7);
s3.insert(2);
s3.insert(4);
s3.insert(5);
s3.insert(1);
s3.insert(9);
for (set<int/*,mycompare*/>::iterator it2 = s3.begin(); it2 != s3.end(); it2++)
{
cout << *it2 << " ";
}
cout << endl;
}
//查找
void text02()
{
//实值
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
s1.insert(9);
set<int>::iterator ret = s1.find(4);//不存在返回end()的值
if (ret == s1.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "ret:" << *ret << endl;
}
//lower_bound(2)找第一个大于等于k的(元素)迭代器值
ret = s1.lower_bound(2);
if (ret == s1.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "ret:" << *ret << endl;
}
//找第一个大于K的值
ret = s1.upper_bound(2);
if (ret == s1.end())
{
cout << "没有找到" << endl;
}
else
{
cout << "ret:" << *ret << endl;
}
//equal_range 返回Lower_bound 和 upper_bound值
pair<set<int>::iterator, set<int>::iterator> myret = s1.equal_range(2);
//这里用到了pair我们在下面补充对组的相关内容。
/*myret.first;
myret.second;*/
if (myret.first == s1.end())
{
cout << "can't find" << endl;
}
else
{
cout << "myret:" << *myret.first << endl;//返回Lower_bound
}
if (myret.second == s1.end())
{
cout << "can't find" << endl;
}
else
{
cout << "myret:" << *myret.second << endl; //返回upper_bound
}
}
class Person
{
public:
Person(int age, int id):id(id),age(age){}
public:
int id;
int age;
};
class mycompare2
{
public:
bool operator()(Person p1, Person p2)const
{
return p1.age > p2.age;
}
};
void text03()
{
set<Person,mycompare2> sp;
Person p1(10, 20), p2(30, 40), p3(50, 60);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
Person p4(10, 20);
for (set<Person, mycompare2>::iterator it = sp.begin(); it != sp.end(); it++)
{
cout << (*it).age << " " << (*it).id << endl;
}
//查找
sp.find(p1);
sp.find(p4);
auto ret = sp.find(p4);//set<Person,mycompare2>::iterator
if (ret == sp.end())
{
cout << "can't find" << endl;
}
else
{
cout << "find:" << (*ret).id << " " << (*ret).age << endl;
}
}
int main()
{
cout <<"text01:"<< endl;
text01();
cout << "text02:" << endl;
text02();
cout << "text03:" << endl;
text03();
return 0;
}
2.8.3 代码运行结果

2.8.4 对组pair的补充
代码实例
//对组的相关内容补充
#include<iostream>
#include<string>
using namespace std;
void text01()
{
//创建对组
//法一
pair<string, int> pair1(string("number"), 20);
cout << pair1.first << " " << pair1.second << endl;
//或者pair<string,int> pair2=make_pair("name",30)
pair<string, int> pair2 = make_pair("name", 30);
cout << pair2.first << " " << pair2.second << endl;
//pair赋值
pair<string, int> pair3 = pair2;
cout << pair2.first << " " << pair2.second << endl;
}
int main()
{
text01();
return 0;
}
运行结果

总结
在刷力扣时,我们发现c++11中的unordered_set也非常常用,我们对比一下就会发现如下结论。
- c++ std中set与unordered_set区别和map与unordered_map区别类似,其底层的数据结构说明如下:
1、set基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的数据,在任何时候,都是有序的。
2、unordered_set基于哈希表,数据插入和查找的时间复杂度很低,几乎是常数时间,而代价是消耗比较多的内存,无自动排序功能。底层实现上,使用一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存。
详情见c++ set与unordered set的区别 - 阿玛尼迪迪 - 博客园 (cnblogs.com)
谢谢阅读(〃’ ▽ '〃)如有纰漏欢迎指出,觉得还不错就点个赞吧。
2.8 C++STL set/multiset容器详解的更多相关文章
- 跟我一起学STL(2)——vector容器详解
一.引言 在上一个专题中,我们介绍了STL中的六大组件,其中容器组件是大多数人经常使用的,因为STL容器是把运用最广的数据结构实现出来,所以我们写应用程序时运用的比较多.然而容器又可以序列式容器和关联 ...
- [STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]
集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...
- STL之vector容器详解
vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...
- [转]STL之vector容器详解
vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...
- [转]STL之list容器详解
List 容器 list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入删除元素. 使用list容 ...
- [转]STL之deque容器详解
Deque 容器 deque容器是C++标准模版库(STL,Standard Template Library)中的部分内容.deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中 ...
- 2.9 C++STL map/multimap容器详解
文章目录 2.9.1 引入 2.9.2 代码示例 map案列 multimap案列 2.9.3 代码运行结果 总结 2.9.1 引入 map相对于set区别,map具有键值和实值,所有元素根据键值自动 ...
- C++ STL bitset 容器详解
C++ STL bitset 容器详解 本篇随笔讲解\(C++STL\)中\(bitset\)容器的用法及常见使用技巧. \(bitset\)容器概论 \(bitset\)容器其实就是个\(01\)串 ...
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
随机推荐
- git每次操作都要输入账号密码 解决方案
1.执行命令: git config --global credential.helper store git pull 2.输入用户名密码,以后就不会再次要求用户名密码了
- java 监听redis事件
第一步:利用RDM等redis连接工具查看相应事件,然后去网上搜索 一下,会有redis各种事件的说明,选择契合业务的事件: 第二步:创建监听处理类: 1 package com.lechuang.a ...
- 汉明码、海明校验码(Hamming Code)
目录 基础知识 汉明码/海明校验码 计算 基础知识 码距:又叫海明距离,是在信息编码中,两个编码之间对应位上编码不同的位数.例如编码100110和010101,第1.2.5.6位都不相同,所以这两个编 ...
- Docker 中的问题:”invalid reference format: repository name must be lowercase”
在导入镜像的时候出现问题:invalid reference format: repository name must be lowercase 问题解决:镜像命名不能出现大写字母,将大写改为小写即可 ...
- 4G无线全网通太阳能水文设备电源监测系统BMS110
钡铼技术BMS110模块可实现4路电池电压.2路模拟量.2路数字量和1路温度测量,支持Modbus RTU over TCP和MQTT通讯协议,DC9-36V电源供电.BMS110可应用于各种有使用蓄 ...
- ScaleFlux CSD 2000 在携程的应用实践
一.业界背景与现状 近些年来,有三件事实在业界同时发生: 1. 业务的发展朝着"生产"和"使用"海量增长数据的方向演进. 2. 摩尔定律 的 ...
- 我们一起来学Shell - 正则表达式
文章目录 什么是正则表达式 正则表达式元字符 正则表达式应用举例 POSIX 方括号表达式 POSIX 字符集列表: 我们一起来学Shell - 初识shell 我们一起来学Shell - shell ...
- 『无为则无心』Python基础 — 44、对文件和文件夹的操作
目录 1.os模块介绍 2.查看os模块相关文档 3.os模块常用方法 (1)文件重命名 (2)删除文件 (3)创建文件夹 (4)删除文件夹 (5)获取当前目录 (6)改变默认目录 (7)获取目录列表 ...
- 1. 堪比JMeter的.Net压测工具 - Crank 入门篇
目录 堪比JMeter的.Net压测工具 - Crank 入门篇 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml 堪比JMeter的.Net压测工具 - Crank 进阶篇 ...
- Python中类的两种用法
第一种用法是使用类生成实例对象.类作为实例对象的模版,每个实例创建后,都将拥有类的所有属性和方法. 第二种用法是用类将多个函数(方法)打包封装在一起,让类中的方法相互配合.