c++ set和unordered_set区别

一.set介绍

C++ 中的 set 容器是一种关联容器,用于存储唯一的元素,并能够根据特定的顺序对元素进行排列。在这里,我们将对 set 容器进行详细的分析。

  • 概述

set 容器是 C++标准库中的一个部分,位于 头文件中。它是一个关联容器,意味着每个元素都是唯一的,并且可以根据特定的顺序对元素进行排列。

  • 特点
  1. 唯一性:set 容器中的元素是唯一的,不允许重复。
  2. 有序性:set 容器中的元素是按照特定的顺序排列的,通常是升序或降序。
  3. 关联性:set 容器是关联容器,意味着每个元素都是唯一的,并且可以根据特定的顺序对元素进行排列。
  • 实现

set 容器的实现是基于红黑树(Red-Black Tree)数据结构的。红黑树是一种自平衡的二叉查找树,它能够维护树的平衡,使得查找、插入和删除操作的时间复杂度保持在 O(log n) 级别。

  • 常用操作
  1. 插入:使用 insert 方法将元素插入到 set 容器中。如果元素已经存在,将不会被插入。
set<int> mySet;
mySet.insert(10);
mySet.insert(20);
  1. 遍历:使用迭代器遍历 set 容器中的元素。
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
    cout << *it << " ";
}
  1. 查找:使用 find 方法在 set 容器中查找特定元素。如果找到,将返回该元素的迭代器;否则,将返回结束迭代器。
auto it = mySet.find(20);
if (it != mySet.end()) {
    cout << "Element found in set";
}
  1. 删除:使用 erase 方法删除 set 容器中的元素。
mySet.erase(10);
  • 优点
  1. 快速查找:set 容器的查找操作非常快,时间复杂度为 O(log n)。
  2. 自动排序:set 容器自动维护元素的顺序,无需手动排序。
  3. 唯一性:set 容器保证元素的唯一性,无需手动检查重复元素。
  • 缺点
  1. 插入慢:set 容器的插入操作相对较慢,时间复杂度为 O(log n)。
  2. 空间占用:set 容器的空间占用相对较高,因为红黑树需要维护树的平衡。
  • 应用场景
  1. 集合操作:set 容器非常适合集合操作,如 union、intersection、difference 等。
  2. 自动排序:set 容器自动维护元素的顺序,无需手动排序。
  3. 快速查找:set 容器的查找操作非常快,时间复杂度为 O(log n)。

二.unordered_set介绍

unordered_set 是 C++11 中引入的一个关联容器,它用于存储唯一的元素,但是不维护元素的顺序。相比于 set 容器,unordered_set 容器提供了更快的查找、插入和删除操作,但牺牲了元素的顺序。

  • 概述

unordered_set 容器是 C++11 中引入的一个关联容器,位于 <unordered_set> 头文件中。它是一个无序容器,意味着元素的顺序是无关紧要的。

  • 特点
  1. 唯一性:unordered_set 容器中的元素是唯一的,不允许重复。
  2. 无序性:unordered_set 容器中的元素是无序的,元素的顺序无关紧要。
  3. 快速查找:unordered_set 容器提供了非常快的查找操作,时间复杂度为平均 O(1),最坏 O(n)。
    快速插入和删除:unordered_set 容器提供了非常快的插入和删除操作,时间复杂度为平均 O(1),最坏 O(n)。
  • 实现

unordered_set 容器的实现是基于 hash table 数据结构的。hash table 使用哈希函数来将元素映射到容器中的索引上,使得查找、插入和删除操作变得非常快。

  • 常用操作
  1. 插入:使用 insert 方法将元素插入到 unordered_set 容器中。如果元素已经存在,将不会被插入。
unordered_set<int> mySet;
mySet.insert(10);
mySet.insert(20);
  1. 遍历:使用迭代器遍历 unordered_set 容器中的元素。
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
    cout << *it << " ";
}
  1. 查找:使用 find 方法在 unordered_set 容器中查找特定元素。如果找到,将返回该元素的迭代器;否则,将返回结束迭代器。
auto it = mySet.find(20);
if (it != mySet.end()) {
    cout << "Element found in set";
}
  1. 删除:使用 erase 方法删除 unordered_set 容器中的元素。
mySet.erase(10);
  • 优点
  1. 快速查找:unordered_set 容器提供了非常快的查找操作,时间复杂度为平均 O(1),最坏 O(n)。

  2. 快速插入和删除:unordered_set 容器提供了非常快的插入和删除操作,时间复杂度为平均 O(1),最坏 O(n)。

  3. 低内存占用:unordered_set 容器的内存占用相对较低,因为hash table 需要的内存空间少。
    缺点

  4. 无顺序:unordered_set 容器中的元素是无序的,无法维护元素的顺序。

  5. 可能存在哈希碰撞:如果哈希函数不够完善,可能会出现哈希碰撞,导致查找、插入和删除操作变得慢。

  • 应用场景
  1. 快速查找:unordered_set 容器非常适合需要快速查找操作的场景。
  2. ** cache实现**:unordered_set 容器可以用于实现 cache,快速地查找和存储缓存内容。
  3. 集合操作:unordered_set 容器可以用于实现集合操作,如 union、intersection、difference 等。

三.两者选择场景

set 和 unordered_set 都是 C++ 的关联容器,用于存储唯一的元素,但是它们有不同的实现和特点,选择哪一个取决于具体的使用场景和需求。

  • 选择 set 的场景
  1. 需要有序:如果需要元素保持特定的顺序,例如按照升序或降序排列,那么 set 是不二之选。set 使用红黑树作为底层数据结构,能够维护元素的顺序。
  2. 需要遍历元素:如果需要遍历整个容器,例如 foreach 循环,set 提供了更好的遍历性能,因为红黑树的遍历效率高于哈希表。
  3. 元素类型支持排序:如果元素类型支持排序,例如 int、string 等,那么 set 可以使用这个排序规则来维护元素的顺序。
  • 选择 unordered_set 的场景
  1. 需要快速查找:如果需要快速查找特定元素,例如频繁地查找特定元素,那么 unordered_set 是不二之选。unordered_set 使用哈希表作为底层数据结构,能够提供 O(1) 的平均查找时间。
  2. 需要快速插入和删除:如果需要频繁地插入和删除元素,那么 unordered_set 是不二之选。unordered_set 提供了 O(1) 的平均插入和删除时间。
  3. 元素类型不支持排序:如果元素类型不支持排序,例如自定义类, 那么 unordered_set 是不二之选,因为哈希表不需要元素类型支持排序。
  • 其他考虑因素
  1. 内存占用:unordered_set 通常需要更少的内存,因为哈希表需要的内存空间少。
  2. 哈希函数:如果使用 unordered_set,需要提供一个良好的哈希函数,以避免哈希碰撞。
  3. ** Collision resolution**:如果使用 unordered_set,需要选择合适的 Collision resolution 策略,以避免哈希碰撞。
  • 结论

如果需要元素保持顺序或需要遍历整个容器,选择 set。如果需要快速查找、插入和删除元素,并且元素类型支持哈希函数,那么选择 unordered_set。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

带安全启动—Ubuntu系统—手动安装Nvidia驱动

教程1&#xff1a;在启用安全启动的 Fedora 中安装英伟达驱动 教程2&#xff1a;UEFI安全启动模式下安装Ubuntu的NVIDIA显卡驱动 1. 搜索合适的驱动 Nvidia驱动官网 选择这个 驱动(.run)链接 2. 安装必要的软件依赖 CUDA底层用C写的&#xff0c;因此导入编译器 sudo apt i…

1-4.时间序列数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…

已解决java.io.NotSerializableException:对象不支持序列化的正确解决方法,亲测有效!!!

已解决java.io.NotSerializableException&#xff1a;对象不支持序列化的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 示例代码 报错原因 解决思路 解决方法 1. 实现Serializable接口 修改后的Employee类 2…

递归----计算P函数

注意运算中的符号不能少&#xff01;&#xff01;&#xff01;&#xff01; * 必须体现出&#xff01;&#xff01;&#xff01;&#xff01; #include <stdio.h>double P( int n, double x );int main() {int n;double x;scanf("%d %lf", &n, &x);pri…

计算机毕业设计Python+Spark股票基金推荐与预测系统 股票基金可视化 股票基金推荐系统 股票基金可视化系统 股票基金数据分析 股票基金爬虫大数据

目 录 摘 要 Abstract 第1章 前 言 1.1 项目的背景和意义 1.2 研究现状 1.3 项目的目标和范围 1.4 论文结构简介 第2章 技术与原理 2.1 开发原理 2.2 开发工具 2.3 关键技术 第3章 需求建模 3.1 系统可行性分析 3.2 功能需求分析 3.3 非功能性…

opengl箱子的显示

VS环境配置&#xff1a; /JMC /ifcOutput "Debug\" /GS /analyze- /W3 /Zc:wchar_t /I"D:\Template\glfwtemplate\glfwtemplate\assimp" /I"D:\Template\glfwtemplate\glfwtemplate\glm" /I"D:\Template\glfwtemplate\glfwtemplate\LearnOp…

Wireshark - tshark支持iptables提供数据包

tshark现在的数据包获取方式有两种&#xff0c;分别是读文件、网口监听&#xff08;af-packet原始套接字&#xff09;。两种方式在包获取上&#xff0c;都是通过读文件的形式&#xff1b;存在文件io操作&#xff0c;在专门处理大流量的情境下&#xff0c; 我们复用wireshark去做…

小阿轩yx-案例:MySQL主从复制与读写分离

小阿轩yx-案例&#xff1a;MySQL主从复制与读写分离 案例分析 概述 实际生产环境中 如果对数据库读和写都在同一个数据库服务器中操作&#xff0c;无论在安全性、高可用性还是高并发等各个方面都完全不能满足实际需求一般都是通过主从复制&#xff08;Master-Slave&#xf…

Python tkinter: 开发一个目标检测GUI小程序

程序提供了一个用户友好的界面&#xff0c;允许用户选择图片或文件夹&#xff0c;使用行人检测模型进行处理&#xff0c;并在GUI中显示检测结果。用户可以通过点击画布上的检测结果来获取更多信息&#xff0c;并使用键盘快捷键来浏览不同的图片。 一. 基本功能介绍 界面布局&am…

C++封装

1. 封装 1.1. struct 当单一变量无法完成描述需求的时候&#xff0c;结构体类型解决了这一问题。可以将多个类型打包成一体&#xff0c;形成新的类型&#xff0c;这是c语言中的封装 但是&#xff0c;新类型并不包含&#xff0c;对数据类的操作。所有操作都是通过函数的方式进…

CrimsonEDR:一款恶意软件模式识别与EDR策略评估工具

关于CrimsonEDR CrimsonEDR是一个功能强大的开源项目&#xff0c;该项目旨在帮助广大研究人员识别特定的恶意软件模式&#xff0c;以此来优化终端检测与响应&#xff08;EDR&#xff09;的策略方案。通过使用各种不同的检测方案&#xff0c;可以加深开发人员与研究人员加深对安…

在Ubuntu 14.04上安装和配置Mumble服务器(Murmur)的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 Mumble是一款免费开源的语音通信应用程序&#xff0c;主要设计用于游戏玩家使用。Mumble类似于TeamSpeak和Ventrilo。Mumble采用客…

考研生活day1--王道课后习题2.2.1、2.2.2、2.2.3

2.2.1 题目描述&#xff1a; 解题思路&#xff1a; 这是最基础的操作&#xff0c;思路大家应该都有&#xff0c;缺少的应该是如何下笔&#xff0c;很多同学都是有思路但是不知道如何下笔&#xff0c;这时候看思路的意义不大&#xff0c;可以直接看答案怎么写&#xff0c;最好…

cube-studio 开源一站式云原生机器学习/深度学习/大模型训练推理平台介绍

全栈工程师开发手册 &#xff08;作者&#xff1a;栾鹏&#xff09; 一站式云原生机器学习平台 前言 开源地址&#xff1a;https://github.com/tencentmusic/cube-studio cube studio 腾讯开源的国内最热门的一站式机器学习mlops/大模型训练平台&#xff0c;支持多租户&…

python sklearn机械学习模型-分类

&#x1f308;所属专栏&#xff1a;【机械学习】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您…

什么是应用安全态势管理 (ASPM):综合指南

软件开发在不断发展&#xff0c;应用程序安全也必须随之发展。 传统的应用程序安全解决方案无法跟上当今开发人员的工作方式或攻击者的工作方式。 我们需要一种新的应用程序安全方法&#xff0c;而ASPM在该方法中发挥着关键作用。 什么是 ASPM&#xff1f; 应用程序安全…

神经网络训练(一):基于残差连接的图片分类网络(ResNet18)

目录 一、简介:二、图片分类网络1.记载训练数据(torch自带的cifa10数据集)2.数据增强3.模型构建4.模型训练三、完整源码及文档一、简介: 基于残差连接的图片分类网络,本网络使用ResNet18作为基础模块,根据cifa10的特点进行改进网络,使用交叉熵损失函数和SGD优化器。本网…

源代码层面分析Appium-inspector工作原理

Appium-inspector功能 Appium Inspector 基于 Appium 框架&#xff0c;Appium 是一个开源工具&#xff0c;用于自动化移动应用&#xff08;iOS 和 Android&#xff09;和桌面应用&#xff08;Windows 和 Mac&#xff09;。Appium 采用了客户端-服务器架构&#xff0c;允许用户通…

实践Go的命令模式

简介 现在的软件系统往往是分层设计。在业务层执行一次请求时&#xff0c;我们很清楚请求的上下文&#xff0c;包括&#xff0c;请求是做什么的、参数有哪些、请求的接收者是谁、返回值是怎样的。相反&#xff0c;基础设施层并不需要完全清楚业务上下文&#xff0c;它只需知道…

Typora导出为Word

文章目录 一、场景二、安装1、网址2、解压并验证 三、配置四、重启Typora 一、场景 在使用Typora软件编辑文档时&#xff0c;我们可能需要将其导出为Word格式文件 当然我们可以直接在菜单里进行导出操作 文件-> 导出-> Word(.docx) 如果是第一次导出word文件&#xff0…