C++ set替换vector进行优化

文章目录

    • demo
      • 代码解释:
    • 底层原理
      • 1. 二叉搜索树基础
      • 2. 红黑树的特性
      • 3. `std::set` 基于红黑树的实现优势
      • 4. 插入操作
      • 5. 删除操作
      • 6. 查找操作

demo

#include <iostream>
#include <set>int main() {// 创建一个存储整数的std::setstd::set<int> mySet;// 插入元素mySet.insert(300);mySet.insert(1);mySet.insert(2);mySet.insert(3);  mySet.insert(3);  // 重复元素不会被插入mySet.insert(300);  // 重复元素不会被插入mySet.insert(300);  // 重复元素不会被插入// 输出集合中的元素std::cout << "Set elements: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 查找元素auto findIt = mySet.find(2);if (findIt != mySet.end()){std::cout << "Element 2 found in the set." << std::endl;} else{std::cout << "Element 2 not found in the set." << std::endl;}// 删除元素mySet.erase(1);std::cout << "Set elements after erasing 1: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 检查集合是否为空if (mySet.empty()) {std::cout << "The set is empty." << std::endl;}else{std::cout << "The set is not empty." << std::endl;}// 获取集合的大小std::cout << "The size of the set is: " << mySet.size() << std::endl;// 清除集合中所有内容mySet.clear();std::cout << "Set elements after clearing: ";for (auto it = mySet.begin(); it != mySet.end(); ++it){std::cout << *it << " ";}std::cout << std::endl;// 再次检查集合是否为空if (mySet.empty()){std::cout << "The set is empty after clearing." << std::endl;} else {std::cout << "The set is not empty after clearing." << std::endl;}return 0;
}    

在这里插入图片描述

代码解释:

  1. 创建集合:使用std::set<int> mySet;创建一个存储整数的std::set
  2. 插入元素:通过insert方法向集合中插入元素,重复元素不会被插入。
  3. 遍历集合:使用迭代器遍历集合中的元素并输出。
  4. 查找元素:使用find方法查找指定元素,如果找到则返回指向该元素的迭代器,否则返回end()
  5. 删除元素:使用erase方法删除指定元素。
  6. 检查集合是否为空:使用empty方法检查集合是否为空。
  7. 获取集合大小:使用size方法获取集合中元素的数量。

底层原理

在C++标准库中,std::set 是一个关联容器,用于存储唯一的元素,并且这些元素会按照一定的顺序排列(默认是升序)。它的底层通常基于红黑树(Red - Black Tree)这种自平衡二叉搜索树(Self - Balancing Binary Search Tree)来实现

1. 二叉搜索树基础

二叉搜索树(Binary Search Tree,BST)是一种二叉树,对于树中的每个节点,其左子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值。这种特性使得在二叉搜索树中进行查找、插入和删除操作的平均时间复杂度为 O ( l o g n ) O(log n) O(logn),其中 n n n 是树中节点的数量。

2. 红黑树的特性

红黑树是一种自平衡的二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色(红色或黑色)。通过对任何一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。红黑树必须满足以下五个性质:

  • 每个节点要么是红色,要么是黑色。
  • 根节点是黑色。
  • 每个叶子节点(NIL节点,空节点)是黑色的。
  • 如果一个节点是红色的,则它的两个子节点都是黑色的。
  • 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

3. std::set 基于红黑树的实现优势

  • 有序性:由于红黑树是一种二叉搜索树,插入到 std::set 中的元素会根据元素的键值自动排序。例如,插入整数时会按照从小到大的顺序排列。
  • 唯一性:在插入元素时,红黑树会进行比较,如果发现元素已经存在,则不会插入,保证了 std::set 中元素的唯一性。
  • 高效的查找、插入和删除操作:红黑树的自平衡特性保证了树的高度始终保持在 O ( l o g n ) O(log n) O(logn) 级别,因此查找、插入和删除操作的时间复杂度都是 O ( l o g n ) O(log n) O(logn)

4. 插入操作

当向 std::set 中插入一个新元素时,底层的红黑树会执行以下步骤:

  • 按照二叉搜索树的规则找到新元素应该插入的位置。
  • 将新元素插入到该位置,并将其颜色设置为红色。
  • 检查红黑树的性质是否被破坏,如果破坏了则通过一系列的颜色调整和旋转操作来恢复红黑树的性质。

5. 删除操作

当从 std::set 中删除一个元素时,红黑树会执行以下步骤:

  • 按照二叉搜索树的规则找到要删除的节点。
  • 如果该节点有两个子节点,则用其右子树中的最小节点替换该节点,然后删除右子树中的最小节点。
  • 删除节点后,检查红黑树的性质是否被破坏,如果破坏了则通过一系列的颜色调整和旋转操作来恢复红黑树的性质。

6. 查找操作

查找操作相对简单,根据二叉搜索树的特性,从根节点开始比较,如果要查找的元素值小于当前节点的值,则在左子树中继续查找;如果大于当前节点的值,则在右子树中继续查找;如果相等,则找到了该元素。由于红黑树的高度为 O ( l o g n ) O(log n) O(logn),因此查找操作的时间复杂度也是 O ( l o g n ) O(log n) O(logn)

综上所述,std::set 基于红黑树实现,利用红黑树的特性保证了元素的有序性、唯一性以及高效的查找、插入和删除操作。

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

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

相关文章

如何巧妙解决 Too many connections 报错?

1. 背景 在日常的 MySQL 运维中&#xff0c;难免会出现参数设置不合理&#xff0c;导致 MySQL 在使用过程中出现各种各样的问题。 今天&#xff0c;我们就来讲解一下 MySQL 运维中一种常见的问题&#xff1a;最大连接数设置不合理&#xff0c;一旦到了业务高峰期就会出现连接…

QT的布局和弹簧及其代码解读

this指的是真正的当前正在显示的窗口 main函数&#xff1a; Widget w是生成了一个主窗口&#xff0c;QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…

《AI大模型应知应会100篇》第52篇:OpenAI API 使用指南与最佳实践

第52篇&#xff1a;OpenAI API 使用指南与最佳实践 &#x1f4cc; 摘要 本文将带你从零开始掌握 OpenAI API 的核心使用方法&#xff0c;涵盖从基础调用到高级功能的完整实战路径。通过详细的代码示例、图文解析和可运行的 Python 脚本&#xff0c;帮助你快速上手 GPT-3.5、GP…

C#学习7_面向对象:类、方法、修饰符

一、类 1class 1)定义类 访问修饰符class 类名{ 字段 构造函数&#xff1a;特殊的方法&#xff08;用于初始化对象&#xff09; 属性 方法... } eg: public class Person { // 字段 private string name; private int a…

湖北理元理律师事务所:债务优化中的“生活保障”方法论

债务危机往往伴随生活质量骤降&#xff0c;如何在还款与生存间找到平衡点&#xff0c;成为债务优化的核心挑战。湖北理元理律师事务所基于多年实务经验&#xff0c;提出“双轨并行”策略&#xff1a;法律减负与生活保障同步推进。 债务优化的“温度法则” 1.生存资金预留机制…

Jetpack Compose与Kotlin UI开发革命

Jetpack Compose + Kotlin:Android UI 开发的革命 简介 Jetpack Compose 是 Google 推出的现代 Android UI 工具包,结合 Kotlin 语言,彻底改变了传统 Android 开发的模式。过去,开发者依赖 XML 布局和命令式编程(如 findViewById 和手动更新视图),导致代码冗长且易出错…

基于pyqt的上位机开发

目录 安装依赖 功能包含 运行结果 安装依赖 pip install pyqt5 pyqtgraph pyserial 功能包含 自动检测串口设备&#xff0c;波特率选择/连接断开控制&#xff0c;数据发送/接收基础框架&#xff0c;实时绘图区域&#xff08;需配合数据解析&#xff09; ""&q…

QT人工智能篇-opencv

第一章 认识opencv 1. 简单概述 OpenCV是一个跨平台的开源的计算机视觉库&#xff0c;主要用于实时图像处理和计算机视觉应用‌。它提供了丰富的函数和算法&#xff0c;用于图像和视频的采集、处理、分析和显示。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&…

Python自学第5天:字符串相关操作

1.字符串运算符 作符描述字符串连接*重复输出字符串[]通过索引获取字符串中字符[ : ]截取字符串中的一部分&#xff0c;遵循左闭右开原则&#xff0c;str[0:2] 是不包含第 3 个字符的。in成员运算符 - 如果字符串中包含给定的字符返回 Truenot in成员运算符 - 如果字符串中不包…

RabbitMq(尚硅谷)

RabbitMq 1.RabbitMq异步调用 2.work模型 3.Fanout交换机&#xff08;广播模式&#xff09; 4.Diret交换机&#xff08;直连&#xff09; 5.Topic交换机&#xff08;主题交换机&#xff0c;通过路由匹配&#xff09; 6.Headers交换机&#xff08;头交换机&#xff09; 6…

分库分表后复杂查询的应对之道:基于DTS实时性ES宽表构建技术实践

1 问题域 业务发展的初期&#xff0c;我们的数据库架构往往是单库单表&#xff0c;外加读写分离来快速的支撑业务&#xff0c;随着用户量和订单量的增加&#xff0c;数据库的计算和存储往往会成为我们系统的瓶颈&#xff0c;业界的实践多数采用分而治之的思想&#xff1a;分库…

CVE-2024-4577:Windows 编码错误

CVE-2024-4577是一个 PHP-CGI 漏洞,就是其中一种情况:虽然有这个版本,但由于 PHP 经常被反向移植,因此无法可靠地使用。 这篇博文详细介绍了如何研究 CVE-2024-4577 以及当前用于检测它的方法。 CVE-2024-4577 CVE-2024-4577 是 Windows 版 PHP 安装中的一个高危漏洞,会…

NetBox Docker 全功能部署方案(Ubuntu 22.04 + Docker)

环境准备 检查操作系统版本&#xff1a; 本方案使用 Ubuntu 22.04&#xff0c;并在 VMware 虚拟机中运行。通过以下命令检查系统版本&#xff1a; lsb_release -a 如果未安装 Ubuntu 22.04&#xff0c;请下载并安装一个全新的系统。 更新系统软件源&#xff1a; 更新软件包列表…

DeepSeek Copilot idea插件推荐

&#x1f30c; DeepSeek Copilot for IntelliJ IDEA 让 AI 成为你的编程副驾驶&#xff0c;极速生成单元测试 & 代码注释驱动开发&#xff01; &#x1f680; 简介 DeepSeek Copilot 是一款为 IntelliJ IDEA 打造的 AI 编程助手插件&#xff0c;它能够智能分析你的代码逻辑…

QT中的JSON

1.JSON的两种数据格式 JSON有两种数据格式:JSON对象和JSON数组 JSON数组&#xff1a; JSON数组格式&#xff1a;[元素1&#xff0c;元素2&#xff0c;元素3&#xff0c;......元素n] JSON数组中的元素可以是同一类型&#xff0c;也可以使不同类型&#xff0c;可以嵌套JSON数组…

详细剖析传输层协议(TCP和UDP)

详细讲解传输层的网络协议&#xff0c;为什么TCP是可靠连接协议&#xff0c;凭什么能做到不丢包&#xff0c;有哪些机制保证可靠呢&#xff1f; TCP/UDP UDPTCP**三次握手和四次挥手****滑动窗口****拥塞控制**&#xff08;socket套接字&#xff09;**listen的第二个参数** UD…

数据可视化:艺术与科学的交汇点,如何让数据“开口说话”?

数据可视化&#xff1a;艺术与科学的交汇点&#xff0c;如何让数据“开口说话”&#xff1f; 数据可视化&#xff0c;是科技与艺术的结合&#xff0c;是让冰冷的数字变得生动有趣的桥梁。它既是科学——讲究准确性、逻辑性、数据处理的严谨性&#xff1b;又是艺术——强调美感…

解决使用lettuce连接Redis超时的问题(tcpUserTimeout 参数失效问题)

问题背景 lettuce 连接Redis的主从实例&#xff0c;当主节的主机异常下电重启后&#xff0c;由于没有发送RST 包&#xff0c;导致 lettuce 一直在复用之前的TCP链接&#xff0c;然后会出现连接超时的情况。一直出现io.lettuce.core.RedisCommandTimeoutException: Command tim…

如何使用python保存字典

在Python中&#xff0c;可以通过多种方式将字典&#xff08;dict&#xff09;保存到文件中&#xff0c;并能够随时读取恢复。以下是几种常见的方法&#xff1a; 1. 使用 json 模块&#xff08;推荐&#xff09; 适用场景&#xff1a;需要人类可读的文件格式&#xff0c;且数据不…

SQL 与 Python:日期维度表创建的不同选择

文章目录 一、日期维度表概述日期维度表结构 二、使用 SQL 创建日期维度表2.1 表结构设计2.2 数据插入2.3 SQL 创建方式的优势与局限 三、使用 Python 创建日期维度表3.1 依赖库引入3.2 代码实现3.3 Python 创建方式的优势与局限 四、应用场景与选择建议4.1 应用场景4.2 选择建…