STL常用容器- set/ multiset 容器

news2024/9/24 23:32:23

set基本概念

set也叫做集合,它的特点就是所有的元素在插入的时候会自动完成排序(默认是升序排列)。

set在物理空间上也不是连续的,所以它就不支持随机存取(利用下标), 它的迭代器也不支持指针算术运算,只能进行++和--。

set的底层的数据结构是红黑树。

可以添加删除元素,但是禁止修改元素,因为修改会导致数的结构发生变化,导致红黑树的结构被破坏,所以set的迭代器是const,set调用的函数也是常函数。

set和multiset的区别

set不允许有重复的元素

multiset允许有重复的元素

方法的使用基本相同,数据结构也相同

树结构的简介

二叉树

任何节点最多只允许有两个子节点,分别是左子节点和右子节点

二叉树的搜索

二叉树中的节点按照一定的规则进行排序,访问效率会更高一些

二叉树放置规则

任何子节点的元素值一定大于左子树中每个节点的元素值,并且小于右子树的值;

所以从根节点一直向左,无路可走时就是最小值,向右无路可走就是最大值。

平衡二叉树

当二叉树的左子树和右子树不平衡的时候,搜索的大小值的时间就会不同,所以会降低我们的搜索效率,所以需要平衡二叉树来保证树的相对平衡;

平衡二叉树左子树的高度和右子树的高度的绝对值要小于等于1。红黑树是一种特殊的平衡二叉树。因此搜索效率会更高。

红黑树

特点:

1、每个节点不是红色就是黑色

2、根节点是黑色的

3、如果一个节点是红色,它的两个子节点都是黑色

4、对于每一个节点,从该节点开始到其所有的后代节点上,均包含相同数目的黑色节点

5、每个叶子节点都是黑色的(叶子节点是空节点)

set的常用方法

特别注意:不可以修改集合元素的值

set构造和赋值

功能描述:创建set容器以及赋值

构造:

set st; //默认构造函数:

set(const set &st); //拷贝构造函数

set<T, 仿函数> st; // 仿函数来制定排序规则,默认升序

赋值:

set& operator=(const set &st); //重载赋值

#include <set>

void printSet(set<int> & s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}

//构造和赋值
void test01()
{

set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
printSet(s1);

//拷贝构造
set<int>s2(s1);
printSet(s2);

//赋值
set<int>s3;
s3 = s2;
printSet(s3);
}

总结:

set容器插入数据时用insert

set容器插入数据的数据会自动排序

set大小和交换

功能描述:统计set容器大小以及交换set容器

函数原型:

size(); //返回容器中元素的数目

empty(); //判断容器是否为空

swap(st); //交换两个集合容器


//大小
void test01()
{
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
if (s1.empty())
{
cout << "s1为空" << endl;
}
else
{
cout << "s1不为空" << endl;
cout << "s1的大小为: " << s1.size() << endl;
}
}

//交换
void test02()
{
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
set<int> s2;
s2.insert(100);
s2.insert(300);
s2.insert(200);
s2.insert(400);
cout << "交换前" << endl;
printSet(s1);
printSet(s2);
cout << endl;
cout << "交换后" << endl;
s1.swap(s2);
printSet(s1);
printSet(s2);
}

总结:

统计大小 --- size

判断是否为空 --- empty

交换容器 --- swap

set插入和删除

功能描述:set容器进行插入数据和删除数据

函数原型:

insert(elem); //在容器中插入元素。

clear(); //清除所有元素

erase(pos) // 删除pos迭代器所指的元素,返回下一个元素的迭代器

erase(beg,end) // 删除区间[beg,end)中的元素,返回下一个元素的迭代器

erase(elem); // 删除容器中值为elem的元素

#include <iostream>
#include <set>
using namespace std;

// 定义通用的打印set的函数模板
template<class T>
void printSet(set<T>& s)
{
	for (auto ele : s)
	{
		cout << ele << " ";
	}
	cout << endl;
}

// 迭代器只有在删除时才会失效
// 插入数据的时候不会导致迭代器失效
void test02()
{
	set<int> s = { 2,3,5,6 };
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		if (*it == 5)
		{
			//it = s.erase(it); // 删除的时候要更新迭代器
			s.insert(it, 0); // 插入不会失效
		}
	}
	printSet(s);
}

总结:

插入 --- insert

删除 --- erase

清空 --- clear

set查找和统计

功能描述:对set容器进行查找数据以及统计数据

函数原型:

find(ele); // 找到并返回迭代器的位置,找不到返回end

count(ele); // 统计ele元素出现的次数,对于set来说元素不能重复,所以结果只有1或者0

// 查找和统计
void test03()
{
	set<int> s1 = { 40,20,30,10 };
	set<int>::iterator pos = s1.find(30);
	if (pos != s1.end())
	{
		cout << "找到了,结果是:" << *pos << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}

	cout << s1.count(30) << endl;
	cout << s1.count(50) << endl;
}

总结:

查找 --- find (返回的是迭代器)

统计 --- count (对于set,结果为0或者1)

set迭代器失效的问题

map、multimap、set、multiset 删除当前的迭代器的时候会失效,只要在earse的时候更新当前的iterator即可。

// 迭代器只有在删除时才会失效
// 插入数据的时候不会导致迭代器失效
void test02()
{
	set<int> s = { 2,3,5,6 };
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
		if (*it == 5)
		{
			//it = s.erase(it); // 删除的时候要更新迭代器
			s.insert(it, 0); // 插入不会失效
		}
	}
	printSet(s);
}

set和multiset区别

set不可以插入重复数据,而multiset可以

set插入数据的同时会返回插入结果,表示插入是否成功

multiset不会检测数据,因此可以插入重复数据

// multiset成员函数和set一样,不同点在于multiset允许重复元素存在
void test04()
{
	multiset<int> ms = { 20,10,30,20 };
	for (auto ele : ms)
	{
		cout << ele << " ";
	}
	cout << endl;

	cout << "20数字出现的次数:" << ms.count(20) << endl;
}

总结:

如果不允许插入重复数据可以利用set

如果需要插入重复数据利用multiset

set的练习

// 手写一个函数对象
template<class T>
class MyCompare
{
public:
	// 实现()运算符的重载
	bool operator()(T v1, T v2)const  // 要成名为常成员函数,因为set禁止修改元素的,属于常对象
	{
		return v1 > v2;
	}
};


// 利用函数模板来遍历用仿函数排序后的set容器
template<class T>
void printSet(set<T, MyCompare<T>>& s)
{
	for (auto ele : s)
	{
		cout << ele << " ";
	}
	cout << endl;
}
void test05()
{
	set<int> s1 = { 40,10,20,30 };
	printSet(s1);

	set<int, MyCompare<int>> s2 = { 40,10,20,30 };
	printSet(s2);

	set<int, greater<int>> s3 = { 40,10,20,30 };
	for (auto ele : s3)
	{
		cout << ele << " ";
	}
	cout << endl;
}

// 对于自定义的数据类型,必须指定排序规则才能插入数据,使用仿函数来进行确定
class Person
{
public:
	string m_Name;
	int m_Age;
	Person(string name, int age) :m_Name(name), m_Age(age) {}
	// 加一个展示方法
	void show()
	{
		cout << "姓名:" << m_Name << "\t年龄:" << m_Age << endl;
	}
};

// 定义一个仿函数
class ComparePerson
{
public:
	//在类中重载()运算符
	//声明为常成员函数,因为set禁止修改元素,属于常对象,传参也是常对象
	bool operator()(const Person &p1, const Person &p2) const 
	{
		return p1.m_Age > p2.m_Age;
	}
};
int main()
{
	// 如果是自定义数据类型,那必须要指定排序规则,不然无法插入
	set<Person, ComparePerson> st;
	Person p1("aaa", 10);
	Person p2("bbb", 15);
	Person p3("ccc", 20);
	st.insert(p1);
	st.insert(p2);
	st.insert(p3);

	for (auto ele : st)
	{
		ele.show();
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

filebeat

1、作用 1、可以在本机收集日志2、也可以远程收集日志3、轻量级的日志收集系统&#xff0c;可以在非java环境运行。logstash是在jmv环境中运行&#xff0c;资源消耗很大&#xff0c;启动一个logstash要消耗500M左右的内存&#xff0c;filebeat只消耗10M左右的内存。收集nginx的…

在Jira中使用AI

Jira已经可以使用AI功能了。 如果您使用的是Jira Cloud&#xff0c;您需要请管理员在管理页面中打开AI功能开关。&#xff08;AI功能在Standard版中未提供&#xff0c;请使用Premium或更高级的版本&#xff09;如果您使用的是自己部署的Jira Data Center&#xff0c;您需要请管…

Java中实现文件上传

目录 1、文件上传本地 1.1 原理 1.2 如何使用文件上传 1.2.1 引入文件上传的依赖 1.2.2 配置文件上传拦截器 1.2.3 完成文件上传的代码 2、文件上传oss服务器 2.1 为什么需要上传到oss服务器 2.2 如何使用oss 2.2.1 开启oss服务 2.2.2 在Java中引入依赖 2.2.3 查看自…

HarmonyOS(47) onSizeChange和onAreaChange

onSizeChange和onAreaChange onSizeChangeonAreaChangeonAreaChange和onSizeChange的区别参考资料 onSizeChange 组件区域变化时触发该回调。仅会响应由布局变化所导致的组件尺寸发生变化时的回调。由绘制变化所导致的渲染属性变化不会响应回调&#xff0c;如translate、offse…

深度学习模型服务端部署——flask+gunicorn+supervisor+nginx+docker

前言&#xff1a;深度学习模型经过前期的训练调优评估&#xff0c;最终得到一个精度速度满足要求的模型(.pth, .ckpt&#xff0c;或者.onnx等等格式)&#xff0c;但模型要实际用起来&#xff0c;还得部署起来&#xff0c;部署分为在移动端芯片上和服务器上。在移动端芯片部署通…

联邦学习开山之作论文解读与Pytorch实现FedAvg

参考文献&#xff1a;McMahan B, Moore E, Ramage D, et al. Communication-efficient learning of deep networks from decentralized data[C]//Artificial intelligence and statistics. PMLR, 2017: 1273-1282. 参考的文章&#xff1a; 1.联邦学习代码解读&#xff0c;超详细…

Object.defineProperty在Vue2双向绑定中的核心原理及应用

目录 1.Object.defineProperty方法 &#xff08;1&#xff09;介绍 &#xff08;2&#xff09;语法 &#xff08;3&#xff09;descriptor属性描述符 2.Object.defineProperty在Vue2双向绑定的核心原理 3.Object.defineProperty在vue2中的应用 &#xff08;1&#xff09…

专业人士如何选?揭秘4款2024年常用的电脑录屏软件!

在这个数字化时代&#xff0c;无论是教学、演示、游戏直播还是软件操作&#xff0c;电脑录屏软件已经是我们日常工作中的好帮手。但市面上这么多的电脑录屏软件&#xff0c;要想挑一款既专业又好用的&#xff0c;还真是挺让人头疼的。今天&#xff0c;我们就来聊聊四款常用的电…

mybatis开启数据库的驼峰命名

在application.yml文件中添加 mybatis:configuration:map-underscore-to-camel-case: true

powerjob连接postgresql数据库(支持docker部署)

1.先去pg建一个powerjob-product库 2.首先去拉最新的包&#xff0c;然后找到server模块&#xff0c;把mysql的配置文件信息替换成pg的 spring.datasource.hikari.auto-committrue spring.datasource.remote.hibernate.properties.hibernate.dialecttech.powerjob.server.pers…

全自动迷你洗衣机什么牌子好?五款卓越内衣洗衣机大合集!

随着科技的发展&#xff0c;市面上也出现许多便利的小家电。其中被多次讨论起来的莫过于是内衣洗衣机&#xff0c;选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;随着内衣洗衣机的爆火&#xff0c;…

maven仓库密码加密方案原理

前言 有一个要求就是说不能使用明文密码&#xff0c;需要对 settings.xml 文件中的password密码进行加密 原始配置是没有对密码进行加密的 <server><id>gleam-repo</id><username>admin</username><password>admin123</password>&l…

7.2 单变量(多->多),attention/informer

继续上文书写&#xff1a; 1 GRU Attention 收敛速度稳定的很多&#xff0c;你看这些模型是不是很容易搭&#xff0c;像积木一样&#xff1b; def create_model(input_shape, output_length,lr1e-3, warehouse"None"):input Input(shapeinput_shape)conv1 Conv…

怎么给电脑文件加密?实用的四种方法,「重磅来袭」!

小李&#xff1a;“嘿&#xff0c;小张&#xff0c;你上次提到的那个重要项目报告&#xff0c;我放在了电脑里&#xff0c;但总觉得不太安全&#xff0c;万一被误删了或者不小心泄露了怎么办&#xff1f;” 小张&#xff1a;“别担心&#xff0c;小李&#xff0c;给文件加密是…

如何提高工作效率?分享9个高效率工作的方法

如果您的企业正在面临以下问题&#xff1a; 员工敏捷性和生产力降低员工满意度不足利润下降 那么您需要创建一个运营改进指南。 这需要经常更新&#xff0c;因为这不是一次性的努力&#xff0c;而是必须定期进行的持续过程。然而&#xff0c;您的运营改进指南还必须强调优化…

java 垃圾回收器以及JVM调优方式

什么是垃圾&#xff1a; 没有被引用的对象 就是垃圾。 定位的方式 reference count: 引用计数&#xff0c;即在对象上记录着有多少个引用指向它。&#xff08;循环引用无法解决&#xff09; root searching: 根可达算法&#xff0c;根对象包含 线程栈变量&#xff0c;静态变…

bootStrap中操作行详情,删除,修改等操作

点击列表某一行的操作按钮&#xff0c;结合swtich case 出发不同操作

【2024算力大会分会 | SPIE出版】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)

【2024算力大会分会 | SPIE出版】 2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning CCPCDL往届均已完成EI检索&#xff0c;最快会后4个半月完成&#xff01; 2024中…

postgresql 11.17 开发环境rpm安装及扩展安装

进入postgresql安装文件rpm所在文件夹 cd /data460/software 执行 yum local install *.rpm 提示缺少啥依赖就对应yum安装 最后有个依赖比较特殊 Requires: llvm-toolset-7-clang > 4.0.1 You could try using --skip-broken to work around the problem 需要安装centos-re…

Spring WebFlux 整合 r2dbc 的增删改查案例

无障碍阅读方法 微信公众号关注:张家的小伙子 回复:10205文章目录 无障碍阅读方法说明准备创建mysql数据库和数据表创建一个maven项目添加项目依赖包创建项目基本目录接口启动类编写编写application配置添加跨域请求配置创建实体-数据表映射类创建Dao操作类编写自己的增删改…