C++标准模板库(STL)集合 set 关联容器
一. 定义与基本概念
在C++的标准模板库(STL)中,集合(set)是一种关联容器,位于<set>头文件中。用于存储唯一的元素,并且这些元素会按照特定的顺序(默认是升序)自动排列。set内部通常是基于红黑树(一种自平衡二叉搜索树)实现的,这使得它在插入、删除和查找操作上具有较高的效率。
二. 创建set对象
默认构造:可以创建一个空的set对象。
std::set<int> mySet; // 创建了一个空的、用于存储int类型元素的set
从其他容器初始化(范围构造):可以使用另一个容器(如数组、vector等)中的元素来初始化set。
int arr[] = {3, 1, 2}; std::vector<int> v = {5, 4, 6}; std::set<int> mySet1(arr, arr + sizeof(arr)/sizeof(arr[0])); std::set<int> mySet2(v.begin(), v.end());
这里分别使用数组arr和vector v中的元素来初始化set对象mySet1和mySet2。在初始化过程中,重复的元素会被自动去除,因为set只存储唯一的元素。
三. set的基本操作
插入元素
insert()方法:用于向set中插入元素。
std::set<int> mySet; mySet.insert(3); mySet.insert(1); mySet.insert(2);
由于set会自动排序元素,插入后的set中的元素顺序为{1, 2, 3}。
查找元素
find()方法:用于在set中查找指定元素。如果找到元素,则返回指向该元素的迭代器;如果未找到,则返回set的end()迭代器。
std::set<int> mySet = {1, 2, 3}; auto it = mySet.find(2); if (it!= mySet.end()) { std::cout << "Element found" << std::endl; } else { std::cout << "Element not found" << std::endl; }
删除元素
erase()方法:可以删除set中的指定元素。可以通过元素值或者迭代器来指定要删除的元素。
std::set<int> mySet = {1, 2, 3}; mySet.erase(2);
这里通过元素值删除了元素2;也可以使用迭代器删除元素。
auto it = mySet.find(3); if (it!= mySet.end()) { mySet.erase(it); }
遍历set
由于set中的元素是有序的,可以使用迭代器遍历set来获取元素。
std::set<int> mySet = {1, 3, 2}; for (auto it = mySet.begin(); it!= mySet.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; //输出结果为1 2 3
获取set的大小:使用size()方法可以获取set中元素的个数。
std::set<int> mySet = {1, 2, 3}; std::cout << mySet.size() << std::endl;//会输出3,表示set中有3个元素
四. set的特性与注意事项
元素的唯一性:set中的元素必须是唯一的。如果尝试插入一个已经存在于set中的元素,插入操作将不会改变set的内容。
std::set<int> mySet = {1, 2}; mySet.insert(2);//执行插入操作后,mySet仍然为{1, 2}
排序规则:默认情况下,set按照元素的<(小于)运算符进行排序。对于自定义类型,如果要存储在set中,需要定义<运算符或者提供自定义的比较函数(在set的模板参数中指定)。
struct Person { std::string name; int age; bool operator<(const Person& other) const { return age < other.age; } }; std::set<Person> people; Person p1 = {"Alice", 25}; Person p2 = {"Bob", 30}; people.insert(p1); people.insert(p2);
时间复杂度:插入、删除和查找操作的平均时间复杂度都是$O(log n)$,其中n是set中的元素个数。这是因为set基于红黑树实现,红黑树的高度始终保持在$O(log n)$的范围内,从而保证了这些操作的高效性。
与其他容器的比较
与vector相比,vector是顺序容器,元素的存储顺序取决于插入顺序,并且允许元素重复。而set是关联容器,元素自动排序且唯一。
与map相比,map是键 - 值对的容器,而set只存储单个元素。虽然在实现上有相似之处(都基于红黑树),但用途不同。例如,std::map<int, std::string>用于存储键(int类型)和值(string类型)的映射关系,而std::set<int>只关注元素(int类型)本身的存储和管理。
C++编程语言基础
- C++:从入门到工作的教程
- 这是我的第一个 C++程序!
- C++中main函数有什么作用?
- C++中 #include 指令的作用
- C++中常用的预处理指令
- C++中 iostream 头文件定义了什么
- C++名称空间(namespace)
- C++标准库中 std 命名空间定义了些什么
- C++常用的头文件
- C++源代码的发布方式
- C++变量名的定义、变量的作用、使用规范
- C++的关键字列表
- C++数据类型:整型(整数类型)
- 二进制补码、原码、反码
- C++数据类型:char字符型(整数类型)
- ASCII码表及C++字符函数库(cctype)
- 计算机汉字编码
- C++数据类型:bool类型(整数类型)
- C++中 const 限定符
- C++数据类型:浮点数
- C++运算符:算术运算符
- C++运算符:类型转换规则
- 计算机数据存储大小端模式
- C++运算符:位运算 与 bitset类库
- C++运算符:关系运算符与逻辑运算符
- C++流程控制:顺序、选择、循环、跳转语句
- C++函数的定义、参数传递、重载、嵌套
- C++数组:一维、二维、多维数组的运用
- C-style字符串、库函数 与 std::string对象
- C++数据类型:结构体(struct)
- C++数据类型:联合体(union)
- C++数据类型:枚举(enum)
- C++数据类型别名:typedef
- C++指针
- C++内存操作符:new分配 与 delete释放
- C++标准模板库(STL)容器、算法、迭代器
- C++标准模板库(STL)vector顺序容器
- C++标准模板库(STL)array固定容器
- C++标准模板库(STL)list双向链表容器
- C++标准模板库(STL)deque双端队列
- C++标准模板库(STL)集合 set 关联容器
- C++标准模板库(STL)map关联容器
- C++标准模板库(STL)unordered_set
- C++标准模板库(STL)unordered_map
- C++标准模板库(STL)algorithm算法库
- C++文件操作
- C++数学库(cmath)数学常量与数学函数
- C++模板:函数模板、类模板
- C++与SQLite3联合打造实用的应用程序
- C++实战开发中常用的库(概述)
- 第二部分:C++面向对象编程
- C++:类的定义与声明、类对象应用
- 第三部分:数据结构与算法(概述)
- 第一部分:C++语言简介与学习路线