Set/Multiset 集合使用的是红黑树的平衡二叉检索树的数据结构,来组织泛化的元素数据,通常来说红黑树根节点每次只能衍生出两个子节点,左面的节点是小于根节点的数据集合,右面的节点是大于根节点的集合,通过这样的方式将数据组织成一颗看似像树一样的结构,而平衡一词的含义则是两边的子节点数量必须在小于等1的区间以内。

Set集合天生去重,所有元素都会根据元素的键值自动的排序,并且Set元素在确定后无法进行更改,换句话说Set的Iterator是一种Const_iterator,而Multiset则允许出现重复的数据,如需使用只需要将set<int>改为multiset<int>即可,Multiset操作方式与API函数与Set集合保持相同。

5.1 正反向遍历集合元素

这段C++代码使用了STL的set容器,展示了set容器的一些基本操作,包括插入元素、删除元素、判断容器是否为空以及遍历元素并按照一定规则排序。

代码首先创建了一个空的set<int>类型的变量var。然后,代码使用insert()函数向set容器中插入了三个整数,并调用PrintSet()函数遍历输出set容器的元素,并按照从大到小的顺序输出。PrintSet()函数中通过判断flag标记的不同来选择正向还是反向输出set容器的元素。

接下来,代码使用empty()函数判断set容器是否为空,并显示容器的元素个数。

最后,代码展示了erase()函数的用法,从set容器中删除了第一个元素和元素值为99的元素,并再次调用PrintSet()函数输出set容器的元素。

  1. #include <iostream>
  2. #include <set>
  3. using namespace std;
  4. void PrintSet(set<int>& s ,int flag)
  5. {
  6. if (flag == 1)
  7. { // 正向遍历元素
  8. for (set<int>::iterator it = s.begin(); it != s.end(); it++)
  9. cout << (*it) << " ";
  10. }
  11. else if (flag == 0)
  12. { // 反向遍历元素
  13. for (set<int>::reverse_iterator it = s.rbegin(); it != s.rend(); it++)
  14. cout << (*it) << " ";
  15. }
  16. }
  17. int main(int argc, char* argv[])
  18. {
  19. set<int> var { };
  20. var.insert(56);
  21. var.insert(67); // 插入元素
  22. var.insert(99);
  23. PrintSet(var,0); // 打印并从大到小排列
  24. if (var.empty()) // 判断是否为空
  25. cout << "None" << endl;
  26. else
  27. cout << "size: " << var.size() << endl;
  28. var.erase(var.begin()); // 删除第一个元素
  29. var.erase(99); // 删除99这个元素
  30. PrintSet(var, 0); // 打印并从大到小排列
  31. system("pause");
  32. return 0;
  33. }

5.2 查找集合中指定元素

这段C++代码使用了STL的set容器,展示了set容器的一些基本操作,包括查找元素、计算元素个数、寻找较大或较小的元素和查找范围。

代码首先创建了一个set<int>类型的变量var,并在其中插入了一些整数。然后,代码分别使用了find()count()函数来查找元素90是否存在于set容器中,并统计了90出现的次数。

代码接下来展示了lower_bound()upper_bound()函数的用法。其中lower_bound()函数返回第一个值大于或等于给定值的元素的迭代器,upper_bound()函数返回第一个值大于给定值的元素的迭代器。在本例中,代码使用lower_bound()函数和upper_bound()函数来查找set中与值4相邻的元素,并输出了它们的值。

最后,代码展示了equal_range()函数的用法。equal_range()函数返回一个pair,其中第一个迭代器指向set中第一个等于所给值的元素,第二个迭代器指向set中第一个大于所给值的元素。在本例中,代码使用equal_range()函数来查找值为4的元素在set中的范围,并输出了这个范围中的元素。

  1. #include <iostream>
  2. #include <set>
  3. using namespace std;
  4. int main(int argc, char* argv[])
  5. {
  6. set<int> var { 23,44,56,78,90,0,90,12,54,67,85,3,4,7};
  7. // 寻找set集合中数值是90的
  8. set<int>::iterator pos = var.find(90);
  9. if (pos != var.end()) // 寻找90是否存在
  10. cout << "找到了: " << *pos << endl;
  11. // count(key) 查找90存在几个,对于set而言返回结果是 1或者0
  12. int number = var.count(90);
  13. cout << "90是否存在: " << number << endl;
  14. // lower_bound(keyElem); 返回第一个 key>=keyElem 元素的迭代器
  15. set<int>::iterator it = var.lower_bound(4); // 寻找4是否存在
  16. if (it != var.end())
  17. cout << "找到了 lower_bound(4) 的值:" << *it << endl;
  18. // upper_bound(keyElem); 返回第一个 key>keyElem 元素的迭代器
  19. set<int>::iterator it2 = var.upper_bound(4); // 寻找4相邻值
  20. if (it2 != var.end())
  21. cout << "找到了 upper_bound(4) 的值:" << *it2 << endl;
  22. // equal_range(keyElem) 返回容器中key与keyElem相等的上下限的两个迭代器.
  23. // 下限就是 lower_bound 上限就是 upper_bound 需要分别迭代输出
  24. pair<set<int>::iterator, set<int>::iterator> ret = var.equal_range(4);
  25. if (ret.first != var.end())
  26. cout << "找到 lower_bound(4): " << *(ret.first) << endl;
  27. if (ret.second != var.end())
  28. cout << "找到 upper_bound(4): " << *(ret.second) << endl;
  29. system("pause");
  30. return 0;
  31. }

5.3 设置默认集合排序方式

这是一个使用STL中的set容器进行数据存储和排序的示例代码,其中使用了自定义比较函数MyCompare以实现按从大到小的顺序进行排序。set 是一个有序不重复元素集合,它是通过红黑树实现的,插入、删除和查找元素的平均时间复杂度都是O(log n)。在此代码中,set容器存储了int类型的数据,并使用MyCompare作为元素的比较方式,从而实现按从大到小的顺序排序。可以看到,通过set容器和自定义比较函数,我们可以非常方便地实现数据存储和排序的功能。

  1. #include <iostream>
  2. #include <set>
  3. #include <string>
  4. using namespace std;
  5. class MyCompare
  6. { // 通过仿函数,重载小括号,实现默认从大到小排列
  7. public: bool operator()(int v1, int v2) {
  8. return v1 > v2; // 从大到小
  9. // return v1 < v2; 从小到大
  10. }
  11. };
  12. int main(int argc, char* argv[])
  13. {
  14. set<int, MyCompare> var;
  15. var.insert(6);
  16. var.insert(3);
  17. var.insert(9);
  18. for (set<int, MyCompare>::iterator it = var.begin(); it != var.end(); it++)
  19. cout << *it << endl;
  20. system("pause");
  21. return 0;
  22. }

5.4 向集合插入自定义类型

这段代码演示了如何在set容器中插入自定义的Person数据类型,并且通过重载运算符实现自定义的比较规则。通过MyCompare类定义的比较方法,实现了set容器中自定义类型的降序排列。最后,通过迭代器遍历容器,输出每个Person对象的名字和年龄。

  1. #include <iostream>
  2. #include <set>
  3. #include <string>
  4. using namespace std;
  5. class Person {
  6. public:
  7. string m_name;
  8. int m_age;
  9. public: Person(string name, int age) {
  10. this->m_name = name;
  11. this->m_age = age;
  12. }
  13. };
  14. class MyCompare{
  15. // 通过仿函数,重载,实现默认降序排列
  16. public: bool operator()(const Person & p1, const Person & p2){
  17. if (p1.m_age > p2.m_age) // 指定为降序排列
  18. return true;
  19. return false;
  20. }
  21. };
  22. int main(int argc, char* argv[])
  23. {
  24. set<Person,MyCompare> var;
  25. Person p1("dawa", 22); // 初始化
  26. Person p2("xiwa", 44);
  27. var.insert(p1); // 插入自定义数据类型
  28. var.insert(p2);
  29. // 显示出自定义类型
  30. for (set<Person, MyCompare>::iterator it = var.begin(); it != var.end();it ++)
  31. {
  32. cout << "Name: " << (*it).m_name << "Age: " << (*it).m_age << endl;
  33. }
  34. system("pause");
  35. return 0;
  36. }

5.1 C++ STL 集合数据容器的更多相关文章

  1. EUI库 - 9 - 数据集合 - 数据容器

      DataGroup 设置一个数据源 自动创建内部所需的对象 来完成数据展示   还要设置单条数据的模板  叫ItemRenderer   继承关系 eui.List  eui.ListBase e ...

  2. STL——关联式容器

    一.关联式容器 标准的STL关联式容器分为set(集合)/map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和 multimap(多键映射表).这些容器的底层机制均以RB-tre ...

  3. STL之map容器的详解

    一.关于map的介绍 map是STL的 一个容器,和set一样,map也是一种关联式容器.它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键 字的值)的数据 ...

  4. C++ STL 中 map 容器

    C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...

  5. STL关联式容器使用注意、概念总结

    引入 继上文 STL序列式容器使用注意.概念总结 继续总结关联式容器的概念以及一些使用事项. 关联式容器与容器适配器 基础容器 STL 中的关联式底层容器:RB tree, hash table,可以 ...

  6. C++ STL之list容器的基本操作

    由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处. 特别注意的地方: (1)STL中迭代器容器中 ...

  7. stl中的容器、迭代器和算法----vector中的find实现

    来源 http://blog.csdn.net/huangyimin/article/details/6133650 stl包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的 ...

  8. 带你深入理解STL之Vector容器

    C++内置了数组的类型,在使用数组的时候,必须指定数组的长度,一旦配置了就不能改变了,通常我们的做法是:尽量配置一个大的空间,以免不够用,这样做的缺点是比较浪费空间,预估空间不当会引起很多不便. ST ...

  9. java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类

    本文关键词: java集合框架  框架设计理念  容器 继承层级结构 继承图 集合框架中的抽象类  主要的实现类 实现类特性   集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...

  10. STL序列式容器学习总结

    STL序列式容器学习总结 参考资料:<STL源码剖析> 参考网址: Vector: http://www.cnblogs.com/zhonghuasong/p/5975979.html L ...

随机推荐

  1. C++正则表达式的初步使用

    正则表达式(Regular Expressions),又被称为regex.regexp 或 RE,是一种十分简便.灵活的文本处理工具.它可以用来精确地找出某文本中匹配某种指定规则的内容.从C++11开 ...

  2. 「Codeforces 1131D」Gourmet Choice

    Description 美食家 Apple 先生是一家美食杂志的主编.他会用一个正整数来评价每一道菜. 美食家在第一天品尝第 $n$ 道菜,第二天品尝了 $m$ 道菜.他制作了一张 $n\times ...

  3. 详解KubeEdge EdgeMesh v1.15 边缘CNI特性

    本文分享自华为云社区<KubeEdge EdgeMesh v1.15 边缘CNI特性原理及功能详解>,作者:达益鑫 |南开大学,刘家伟.吴锟 |DaoCloud,王杰章 |华为云 特性研发 ...

  4. SCA技术进阶系列(一):SBOM应用实践初探

    现代软件都是组装的而非纯自研.随着开源组件在数字化应用中的使用比例越来越高,混源开发已成为当前业内主流开发方式.开源组件的引入虽然加快了软件开发效率,但同时将开源安全问题引入了整个软件供应链.软件组成 ...

  5. nginx安装 没有网络且缺少基础包的环境下

    一.安装 [root@oracle ~]# cd /etc/yum.repos.d/ [root@oracle yum.repos.d]# rm -rf * [root@oracle yum.repo ...

  6. <vue 基础知识 7、循环遍历>

    代码结构 一.     01-v-for遍历数组 1.效果 2.代码 01-v-for遍历数组.html <!DOCTYPE html> <html lang="en&qu ...

  7. C# Redis的五大数据结构相关操作及应用场景

    Cache和NoSql.Redis ServiceStack.Redis 下面额代码类均是通过 ServiceStack.Redis 来对Redis进行各种操作 redis 文件配置类 /// < ...

  8. spring boot 集成配置阿里 Druid监控配置

    本文为博主原创,转载请注明出处: github 地址如下:https://github.com/alibaba/druid/wiki 其相关问题也可参考:https://github.com/alib ...

  9. 【LINT】cpplint 分析笔记

    cpplint 分析笔记 · [前提得看下google规范] @2022-1-13 20:44:48 error message formate: [filename] [linenum] [mess ...

  10. 【ES系列】(一)简介与安装

    首发博客地址 首发博客地址 系列文章地址 教学视频 为什么要学习 ES? 强大的全文搜索和检索功能:Elasticsearch 是一个开源的分布式搜索和分析引擎,使用倒排索引和分布式计算等技术,提供了 ...