news 2026/6/23 2:52:26

STL——set

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STL——set

1. 核心概念:什么是 set?

std::set是C++标准模板库(STL)中的一种关联式容器。它的核心特性可以概括为以下三点:

  • 唯一性:容器内的所有元素都是唯一的,不允许重复。

  • 有序性:元素在容器中总是按照特定的严格弱序规则进行排序(默认是升序<)。

  • 关键特性元素的value就是key。你无法直接修改set中的元素,因为这可能破坏其有序性。

2. 底层实现:红黑树

这是理解set所有特性的关键。set通常被实现为一颗红黑树,这是一种高效的自平衡二叉搜索树。

  • 二叉搜索树:保证了元素的有序存储,使得查找、插入、删除的平均时间复杂度可以达到O(log n)

  • 自平衡(红黑树):防止在最坏情况下(例如插入有序序列)退化成链表(操作复杂度O(n)),通过旋转和变色规则保持树的相对平衡,保证了最坏情况下的操作复杂度也是O(log n)

3. 基本用法与代码示例

cpp

#include <iostream> #include <set> using namespace std; int main() { // 1. 初始化 set<int> mySet = {5, 2, 8, 2, 1}; // 重复的2只会保留一个 // 此时 mySet 内容为: {1, 2, 5, 8} (已排序) // 2. 插入元素 mySet.insert(3); // 插入 3 auto ret = mySet.insert(5); // 再次尝试插入5 if (!ret.second) { cout << "Insertion failed. Element 5 already exists." << endl; } // 3. 遍历(总是有序输出) cout << "Set elements: "; for (int num : mySet) { cout << num << " "; // 输出: 1 2 3 5 8 } cout << endl; // 4. 查找与计数 auto it = mySet.find(3); if (it != mySet.end()) { cout << "Found: " << *it << endl; } cout << "Count of 2: " << mySet.count(2) << endl; // 输出1 (存在) cout << "Count of 9: " << mySet.count(9) << endl; // 输出0 (不存在) // 5. 删除元素 mySet.erase(2); // 通过值删除 auto it_to_erase = mySet.find(5); if (it_to_erase != mySet.end()) { mySet.erase(it_to_erase); // 通过迭代器删除 } // 6. 常用操作 cout << "Size: " << mySet.size() << endl; cout << "Is empty? " << (mySet.empty() ? "Yes" : "No") << endl; mySet.clear(); // 清空所有元素 return 0; }

4. 进阶特性与重要成员

自定义排序规则

你可以通过提供自定义的比较函数或函数对象来改变元素的排序方式。

cpp

// 示例1:使用greater<int>使set降序排列 set<int, greater<int>> descendingSet = {5, 2, 8, 1}; // 内容为: {8, 5, 2, 1} // 示例2:自定义结构体排序 struct Person { string name; int age; }; // 定义比较仿函数:按年龄升序排序 struct CompareByAge { bool operator()(const Person& a, const Person& b) const { return a.age < b.age; } }; set<Person, CompareByAge> personSet;

关键迭代器与方法

除了begin()end()set提供了一些特有的迭代器方法,这对于有序数据的操作非常高效:

  • lower_bound(key):返回第一个 >= key的元素的迭代器。

  • upper_bound(key):返回第一个 > key的元素的迭代器。

  • equal_range(key):返回一个pair,表示等于key的元素范围(对于set,这个范围最多包含一个元素)。

cpp

set<int> s = {10, 20, 30, 40, 50}; auto low = s.lower_bound(25); // 指向30 (第一个 >=25 的元素) auto up = s.upper_bound(35); // 指向40 (第一个 >35 的元素) s.erase(low, up); // 删除区间 [30, 40),即删除30 // 此时 s = {10, 20, 40, 50}

5. 核心特点总结与对比

特性std::setstd::vectorstd::unordered_set
元素顺序严格有序(根据比较规则)插入顺序无序(根据哈希值)
重复元素不允许允许不允许
底层实现红黑树(平衡BST)动态数组哈希表
平均时间复杂度查找/插入/删除:O(log n)查找: O(n), 尾部插入: O(1)查找/插入/删除:O(1)
关键用途需要自动排序且去重的场景随机访问、尾部操作频繁仅需快速查找去重,不关心顺序

6. 典型应用场景

  1. 自动去重与排序:比如需要维护一个不重复的单词列表,并随时按字母顺序输出。

  2. 快速存在性检查:在O(log n)时间内判断一个元素是否存在,且需要数据有序。

  3. 范围查询:利用lower_bound/upper_bound高效查询某个分数区间的学生,或某个价格区间的商品。

7. 需要特别注意的要点

  1. 不可直接修改元素set的迭代器是const的(即使是非常量迭代器)。因为直接修改可能破坏红黑树的有序性。必须先删除旧元素,再插入新元素。

  2. 内存开销:相比vectorunordered_set,红黑树的每个节点都需要额外的指针(指向父节点和左右子节点)以及颜色标记,内存开销更大。

  3. 迭代器稳定性:除了被删除的元素,set的迭代器在插入操作后通常保持有效(因为红黑树是节点式容器)。

理解set的关键在于牢牢抓住其“有序”“唯一”这两个核心,并时刻意识到其底层是一棵红黑树。它在需要有序访问、范围查询的场景下无可替代,但在只要求快速查找、不关心顺序时,unordered_set通常是更优选择。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 3:36:56

[CTF]攻防世界:fakebook (sql注入)

题目&#xff1a;攻防世界&#xff1a;fakebook &#xff08;sql注入&#xff09; 提示&#xff1a;sql注入步骤 进入网站查看下功能点&#xff0c;一个登录一个加入。加入一个注册后自动返回首页&#xff0c;显示出了刚刚注册的用户信息&#xff0c;并且可以点开。这是点开后的…

作者头像 李华
网站建设 2026/6/21 17:16:53

Zepp Life自动刷步终极指南:3分钟搞定微信支付宝同步

Zepp Life自动刷步终极指南&#xff1a;3分钟搞定微信支付宝同步 【免费下载链接】mimotion 小米运动刷步数&#xff08;微信支付宝&#xff09;支持邮箱登录 项目地址: https://gitcode.com/gh_mirrors/mimo/mimotion 想要在微信运动排行榜上脱颖而出&#xff0c;却苦于…

作者头像 李华
网站建设 2026/6/21 22:42:04

FLUX.1-dev与Docker镜像优化:最小化容器体积提升加载速度

FLUX.1-dev与Docker镜像优化&#xff1a;最小化容器体积提升加载速度 在生成式AI快速落地的今天&#xff0c;一个现实问题始终困扰着开发者&#xff1a;如何让动辄数十GB的文生图模型既能保持高性能&#xff0c;又能快速启动、灵活部署&#xff1f;尤其是在本地调试或边缘设备上…

作者头像 李华
网站建设 2026/6/23 10:21:32

Applite:Mac软件管理终极指南,告别命令行烦恼

Applite&#xff1a;Mac软件管理终极指南&#xff0c;告别命令行烦恼 【免费下载链接】Applite User-friendly GUI macOS application for Homebrew Casks 项目地址: https://gitcode.com/gh_mirrors/ap/Applite 对于Mac用户来说&#xff0c;软件管理一直是个让人头疼的…

作者头像 李华
网站建设 2026/6/23 13:15:42

Ollama下载GPT-OSS-20B并实现本地化AI服务的完整教程

本地化AI服务的平民化之路&#xff1a;用Ollama运行GPT-OSS-20B 在生成式AI席卷全球的今天&#xff0c;我们早已习惯了与ChatGPT对话、让大模型写代码、甚至靠它构思整篇文章。但你有没有想过——这些看似智能的服务背后&#xff0c;每一次提问都可能被记录、分析&#xff0c;甚…

作者头像 李华
网站建设 2026/6/23 4:04:22

SkyWalking 与 Zipkin、Prometheus 深度对比分析

目录 一、核心定位与设计目标 二、核心功能能力对比 1. 核心能力覆盖&#xff08;√ 支持&#xff0c;△ 部分支持&#xff0c; 不支持&#xff09; 2. 关键能力细节拆解 &#xff08;1&#xff09;分布式链路追踪 &#xff08;2&#xff09;指标监控 &#xff08;3&…

作者头像 李华