4.关联式容器

关联式container

STL中一些常见的容器:

  1. 序列式容器(Sequence Containers)

    • vector(动态数组): 动态数组,支持随机访问和在尾部快速插入/删除。
    • list(链表): 双向链表,支持在任意位置快速插入/删除。
    • deque(双端队列): 双端队列,支持在两端快速插入/删除。

    容器适配器(Container Adapters):

    • stack(栈): 后进先出(LIFO)的数据结构。
    • queue(队列): 先进先出(FIFO)的数据结构。
    • priority_queue(优先队列): 具有优先级的队列。

  2. 关联式容器(Associative Containers)

    • set(集合): 有序集合,不允许重复元素。
    • multiset(多重集合): 有序集合,允许重复元素。
    • map(映射): 键-值对的集合,按键有序存储,不允许重复键。
    • multimap(多重映射): 键-值对的集合,按键有序存储,允许重复键。

    无序关联容器(Unordered Associative Containers):

    • unordered_set: 无序集合,不允许重复元素。
    • unordered_multiset: 无序集合,允许重复元素。
    • unordered_map: 无序映射,按键无序存储,不允许重复键。
    • unordered_multimap: 无序映射,按键无序存储,允许重复键。

关联式容器

关联式容器是指数据是键值对的格式。容器内部结构(可能是RB-tree或者hash-table)便依照其键值大小,以某种特定规则将这个元素放置于合适的位置,关联式容器没有所谓头尾(只有最大元素和最小元素);所以不会有所谓push_back()push_front()等行为的操作。

1.set

set中所有元素都会根据元素的键值自动被排序。std::set 使用红黑树(一种自平衡的二叉搜索树)作为底层数据结构。

set的元素不像map那样可以同时拥有key和value,set的键值就是实值。并且set不允许两个元素拥有相同的值。

迭代器

std::set 的迭代器性质:

  1. 递增顺序: std::set 中的元素是有序排列的,迭代器按照递增(升序)的顺序遍历元素。这是由底层平衡二叉搜索树的特性决定的。
  2. 双向迭代器: std::set 提供双向迭代器,支持向前(++)和向后(-)遍历。
  3. 随机访问特性的缺失: 与支持随机访问的容器(如 std::vector)不同,std::set 的迭代器不支持 +nn 这样的随机跳跃,因为底层结构并不是一个连续的存储区域。
  4. 不能通过迭代器修改set键值,因为set的元素值关系到set元素的排列,随意改变值,会导致排列顺序崩溃,所以不不能通过迭代器修改set值。

因此插入和删除操作并不会使set迭代器失效。当然,被删除的哪个迭代器除外。


set的核心在于使用的红黑树的insert_unique插入数据。

在这里插入图片描述

2.map

map所有元素都会根据元素的键值自动被排序。std::map 也是使用红黑树(一种自平衡的二叉搜索树)作为底层数据结构。

map的所有元素都是pair,同时拥有实值(value)和键值(key)。pair的第一元素被视为键值,第二元素被视为实值。map不允许两个元素拥有相同的键值。

pair的定义:

template<class T1,class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair():first(T1()),second(T2()){}pair(const T1& a,const T2& b):first(a),second(b){}    
};

map和set一样的核心在于使用的红黑树的insert_unique插入数据。

在这里插入图片描述

迭代器

map和set的迭代器性质一样。

  • 递增顺序
  • 双向迭代器
  • 随机访问特性缺少
  • 不能通过迭代器修改map键值。但是可以通过迭代器修改键值对应的实值。
int main() {std::map<int, std::string> myMap;// 插入元素myMap[1] = "One";myMap[2] = "Two";myMap[3] = "Three";// 使用迭代器遍历并修改值for (auto it = myMap.begin(); it != myMap.end(); ++it) {std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;//it->first = 4; //报错// 修改值it->second = "Modified";}for (auto it = myMap.begin(); it != myMap.end(); ++it) {std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;}return 0;
}

关联式容器的find方法

在这里插入图片描述

3.multiset

multiset的特性以及用法和set完全相同,唯一的差别在于它允许键值重复。

它的底层机制是使用RB-tree的insert_equal()而非insert_unique();

在这里插入图片描述

4.multimap

与map的用法完全相同,唯一的差别在于,它允许键值重复。

它的底层机制是使用RB-tree的insert_equal()而非insert_unique();

在这里插入图片描述

5.hashtable

上述提到的以红黑树做为底层结构的set、map,其查找的时间复杂度为对数,但是依赖于元素值是要有足够的随机性。例如输入数据完全有序或完全逆序,红黑树可能会退化成链表,导致性能下降至O(n)。

HashTable 是一种通过哈希函数将关键字映射到存储桶的数据结构。STL中的HashTable通常是一个数组,每个数组元素是一个链表或其他形式的容器。当有多个关键字哈希到同一个存储桶时,它们被放入同一个链表中。

使用哈希函数会遇到一个问题,可能有不同的元素被映射到相同的位置,这就是所谓的hash碰撞问题。解决hash碰撞问题有很多,包括线性探测、二次探测、开链法等。

线性探测

线性探测的基本操作:

  1. 插入操作

    • 根据散列函数计算键的散列值。
    • 如果该位置为空,则将键值对插入该位置。
    • 如果该位置已被占用,就向后线性探测,查找下一个空闲位置,直到找到一个空闲位置为止,然后插入键值对。
  2. 查找操作

    • 根据散列函数计算键的散列值。
    • 如果该位置为空,表示键不存在。
    • 如果该位置不为空,检查键是否匹配,如果匹配则找到了键,返回对应的值;否则,向后线性探测,查找下一个位置,直到找到匹配的键或者遇到空位置为止。
  3. 删除操作

    • 查找要删除的键。
    • 如果找到,将该位置标记为空,表示删除该键。注意:在某些实现中,可以使用特殊的标记表示已删除的位置,而不是直接将位置设置为空。被叫做惰性删除,实际的删除操作等到整理表的时候再删。

    具体的探测序列可以表示为:
    在这里插入图片描述

二次探测

二次探测是解决散列表冲突的一种方法,类似于线性探测,但是在寻找下一个可用位置时,不是简单地线性向后移动,而是使用一个二次方程来计算下一个位置。这样可以更灵活地处理冲突,减少聚集的可能性。
在这里插入图片描述
二次探测的优点是相对于线性探测,能够更好地分散冲突,减少聚集问题。然而,如果HashTable的大小选择不当,仍然可能发生聚集问题。

开链法

开链法的做法是为每一个表格元素维护一个list。通过哈希函数定位到某一个list,然后在那一个list上执行插入、搜寻、删除操作。

使用开链法,哈希表的负载系数将大于1。上述的线性探测和二次探测的负载系数都是小于1的。

开链法由一个bukets vector和一个bucket list组成。
在这里插入图片描述
在这里插入图片描述

迭代器

在这里插入图片描述

hash_set、hash_map、hash_multiset、hash_multimap

hash_set以hashtable为底层机制。由于hash_set所供应的操作接口。 注意:hash_table中没有自动排序功能。

hash_map、hash_multiset、hash_multimap基本都与对应的类型相同,只是底层机制由hash_table来进行实现。

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

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

相关文章

【接口测试】常见HTTP面试题

目录 HTTP GET 和 POST 的区别 GET 和 POST 方法都是安全和幂等的吗 接口幂等实现方式 说说 post 请求的几种参数格式是什么样的&#xff1f; HTTP特性 HTTP&#xff08;1.1&#xff09; 的优点有哪些&#xff1f; HTTP&#xff08;1.1&#xff09; 的缺点有哪些&#x…

Nginx高级技巧:实现负载均衡和反向代理

文章目录 Nginx概述Nginx作用正向代理反向代理负载均衡动静分离 Nginx的安装 -->Docker3.1 安装Nginx3.2 Nginx的配置文件3.3 修改docker-compose文件 Nginx源码安装nginx常用命令nginx配置文件配置文件位置配置文件结构详情 Nginx的反向代理【重点】基于Nginx实现反向代理4…

会声会影2024中文官方网站https://wm.makeding.com/iclk/?zoneid=55677

会声会影2024在易用性方面做得非常出色&#xff0c;这也是它受到广大用户喜爱的一个重要原因。 首先&#xff0c;会声会影2024拥有直观的用户界面设计。软件的整体布局清晰明了&#xff0c;各个功能模块划分得十分合理。用户即使是第一次使用&#xff0c;也能够迅速找到所需的…

实战 | 使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)

导 读 本文主要介绍使用YOLOv8图像分割实现路面坑洞检测&#xff08;步骤 代码&#xff09;。 背 景 如上图所示&#xff0c;现实生活中路面坑洞对车辆和驾驶员安全来说存在巨大隐患&#xff0c;本文将介绍如何使用YoloV8图像分割技术来检测路面坑洞&#xff0c;从而提示驾…

【大数据Hive】hive 多字段分隔符使用详解

目录 一、前言 二、hive默认分隔符规则以及限制 2.1 正常示例&#xff1a;单字节分隔符数据加载示例 2.2 特殊格式的文本数据&#xff0c;分隔符为特殊字符 2.2.1 文本数据的字段中包含了分隔符 三、突破默认限制规则约束 3.1 数据加载不匹配情况 1 3.2 数据加载不匹配…

理解python3中的回调函数

百度百科说&#xff1a;回调函数就是一个通过函数指针调用的函数。如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;我们就说这是回调函数。回调函数不是由该函数的实现方直接调用&#…

ctf_show笔记篇(web入门---php特性)

目录 php特性 89&#xff1a;直接数组绕过preg_match当遇到数组时会直接报错输出0 90&#xff1a;这里利用了intval的特性 91&#xff1a;这里需要细节一点 92-93&#xff1a;这两题的方法很多可以发散思维 94&#xff1a;还是利用小数绕过例如4476.0 95&#xff1a;这里…

【ArcGIS】统计格网中不同土地利用类型占比

基于ArcGIS统计格网中不同土地利用类型占比 数据准备ArcGIS操作步骤1、创建渔网&#xff08;Create Fishnet&#xff09;2、建立唯一标识3、选择格网4、提取不同类别土地利用类型5、各类用地面积计算 参考另&#xff1a;可能出现的问题总结Q1&#xff1a;ArcGIS获取唯一值&…

7.1.1 selenium介绍及安装chromedriver

目录 1. Selenium的用途 2. 安装Selenium库 3. 安装chromedriver 1. 查看谷歌版本号​编辑 2. 找到最新版本及下载 3. 配置环境变量 4. 检测是否配置成功 5. 用python初始化浏览器对象检测&#xff1a; 6. 参考链接 1. Selenium的用途 在前面我们提到&#xff1a;在我…

端智能:面向手机计算环境的端云协同AI技术创新

近年来&#xff0c;随着移动端设备软硬件能力的进步&#xff0c;移动端的算力有了很大提升&#xff0c;同时面向移动端的机器学习框架和模型轻量化技术越来越成熟&#xff0c;端上的AI能力逐渐进入大众视野&#xff0c;端智能在电商领域也开始逐步走向规模化应用。通过持续探索…

Leetcoder Day36| 动态规划part03

343. 整数拆分 给定一个正整数 n&#xff0c;将其拆分为至少两个正整数的和&#xff0c;并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 1: 输入: 2输出: 1解释: 2 1 1, 1 1 1。 示例 2: 输入: 10输出: 36解释: 10 3 3 4, 3 3 4 36。说明: 你可以假设 …

Day04:APP架构小程序H5+Vue语言Web封装原生开发Flutter

目录 常见APP开发架构 APP-开发架构-原生态-IDEA APP-开发架构-Web封装-平台 APP-开发架构-H5&Vue-HBuilderX WX小程序-开发架构-Web封装-平台 WX小程序-开发架构-H5&Vue-HBuilderX 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服…

ROS开发基础-Linux基础第四部(开发板设置本地IP)

一 、网线连接设备 使用网线连接jetson NX与机械臂&#xff0c;如下图所示&#xff1a; 二、 修改上位机IPV4 IP ①测试是否可连接。网线连接机械臂之后&#xff0c;在桌面打开终端输入命令“ping 192.168.1.18”,如不可正常通信&#xff0c;可按照下述步骤进行设置。 ②在U…

TypeScript08:在TS中使用模块化

前言&#xff1a;tsconfig.json中的配置 一、前端领域中的模块化标准 前端领域中的模块化标准有&#xff1a; ES6、commonjs、amd、umd、system、esnext 二、 TS中如何书写模块化语句 TS 中&#xff0c;导入和导出模块&#xff0c;统一使用 ES6 的模块化标准。 myModule.ts &a…

如何使用ArcGIS Pro创建最低成本路径

虽然两点之间直线最短&#xff0c;但是在实际运用中&#xff0c;还需要考虑地形、植被和土地利用类型等多种因素&#xff0c;需要加权计算最低成本路径&#xff0c;这里为大家介绍一下计算方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…

社区店商业计划书撰写指南:让你的项目脱颖而出

对于想要开实体店或创业的朋友们&#xff0c;撰写一份完整而有说服力的商业计划书是迈向成功的重要一步。 作为一名开鲜奶吧5年的创业者&#xff0c;我将分享一些关键的要点和技巧&#xff0c;帮助你撰写一份出色的社区店商业计划书。 1、项目概述&#xff1a; 在计划书的开头…

Java | Java中与文件同名的类的构造函数的调用

在Java的学习过程中遇到了这样一段代码&#xff1a; public class Test1 {int a1;public static void main(String []args){System.out.println("java");}public Test1(){System.out.println("构造函数");} }它的运行结果是这样的&#xff0c;构造函数中的…

第 1 章 微信小程序与云开发从入门到实践从零开始做小程序——开发认识微信小程序

小北的参考工具书 小程序开发的图书并不少&#xff0c;这本书仍然值得你拥有&#xff01; 首先&#xff0c;这是一本全栈小程序开发教程&#xff0c;循序渐进&#xff0c;由浅入深&#xff0c;介绍了小程序开发你想了解的方方面面&#xff0c;包括近其小程序开发的各种新技术应…

C++中的const总结

const修饰成员函数 用const修饰的成员函数时&#xff0c;const修饰this指针指向的内存区域&#xff0c;成员函数体内不可以修改 本类中的任何普通成员变量&#xff0c; 当成员变量类型符前用mutable修饰时例外。 int myFun(void) const //const修饰的是成员函数 2 {}//函数内…

智慧市容环境卫生管理信息系统建设项目初步设计参考指南

第四章项目建设方案 梳理和编制数据标准规范&#xff0c;为数据体系建设提供建设指导。数据标准规范体系是根据统一市容环卫基础数据资源建立的&#xff0c;从要素分类、编码、符号、制图、更新机制等层 面解决各类规划标准不衔接、各自为政问题。标准规范体系包括&#xff1…