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容器详解的更多相关文章

  1. 跟我一起学STL(2)——vector容器详解

    一.引言 在上一个专题中,我们介绍了STL中的六大组件,其中容器组件是大多数人经常使用的,因为STL容器是把运用最广的数据结构实现出来,所以我们写应用程序时运用的比较多.然而容器又可以序列式容器和关联 ...

  2. [STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]

    集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...

  3. STL之vector容器详解

    vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...

  4. [转]STL之vector容器详解

    vector 容器 vector是C++标准模版库(STL,Standard Template Library)中的部分内容.之所以认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单的说: ...

  5. [转]STL之list容器详解

    List 容器 list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入删除元素. 使用list容 ...

  6. [转]STL之deque容器详解

    Deque 容器 deque容器是C++标准模版库(STL,Standard Template Library)中的部分内容.deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中 ...

  7. 2.9 C++STL map/multimap容器详解

    文章目录 2.9.1 引入 2.9.2 代码示例 map案列 multimap案列 2.9.3 代码运行结果 总结 2.9.1 引入 map相对于set区别,map具有键值和实值,所有元素根据键值自动 ...

  8. C++ STL bitset 容器详解

    C++ STL bitset 容器详解 本篇随笔讲解\(C++STL\)中\(bitset\)容器的用法及常见使用技巧. \(bitset\)容器概论 \(bitset\)容器其实就是个\(01\)串 ...

  9. C++中的STL中map用法详解(转)

    原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解   Map是STL的一个关联容器,它提供 ...

随机推荐

  1. MySQL 数据库SQL语句——高阶版本2

    MySQL 数据库SQL语句--高阶版本2 实验准备 数据库表配置: mysql -uroot -p show databases; create database train_ticket; use ...

  2. Apache——配置与应用

    Apache配置与应用 1.概述 2.httpd服务支持的虚拟主机类型 3.构建虚拟Web主机 4.构建Web虚拟目录与用户授权限制 5.日志分割 6.AWStats分析系统 1.概述: 虚拟web主 ...

  3. python 使用pip安装包的总结

    multiprocessing.logging模块安装 如果使用在cmd中使用 pip install multiprocessing 会报错, 将命令改为 pip3 install multipro ...

  4. DAG(有向无环图)技术

    什么是DAG? DAG的全称为"Directed Acyclic Graph",中文意思为:有向无环图,它由有限个顶点和"有向边"组成,从任意顶点出发,经过若干 ...

  5. Pandas中Series与Dataframe的初始化

    (一)Series初始化 1.通过列表,index自动生成 se = pd.Series(['Tom', 'Nancy', 'Jack', 'Tony']) print(se) 2.通过列表,指定in ...

  6. 【Linux/Oracle】ORA-00031:标记要终止的会话 解决

    在PL/SQL操作了一条delete语句用于删除这张1.4亿条数据的表,执行了12个小时还没删完 (经DB指导,量级大的需要使用truncate table table_name 进行删除) --查询 ...

  7. Solution -「六省联考 2017」「洛谷 P3750」分手是祝愿

    \(\mathcal{Description}\)   Link.   有 \(n\) 盏编号为 \(1\sim n\),已知初始状态的灯,每次操作选取 \(x\in[1,n]\),使得所有编号为 \ ...

  8. Solution -「CF 848D」Shake It!

    \(\mathcal{Description}\)   Link.   初始有一个有向图 \(G=(V,E)\),\(V=\{s,t\}\),\(E=\langle s,t\rangle\),一次操作 ...

  9. C#字符串Unicode转义序列编解码

    C#字符串Unicode转义序列编解码 在开发过程中时常会遇到"\Uxxxx"格式表示的字符,实际上"xxxx"是字符的Unicode码的十六进制表示方式.这种 ...

  10. SpringBoot自定义classloader加密保护class文件

    背景 最近针对公司框架进行关键业务代码进行加密处理,防止通过jd-gui等反编译工具能够轻松还原工程代码,相关混淆方案配置使用比较复杂且针对springboot项目问题较多,所以针对class文件加密 ...