C++ 容器适配器

文章目录

  • 1. 适配器
  • 2. stack和queue
    • 2.1 deque
      • 2.1.1 deque的底层结构
      • 2.1.2 deque如何实现头插和随机访问
    • 2.2 用deque实现栈和队列
    • 2.3 deque的优缺点
  • 3. priority_queue

1. 适配器

适配器是什么?
适配器是一种设计模式,实质上就是一种复用,即将一个类的接口,转换成客户希望的另外一个接口。

本篇博客将通过stack、queue、priority_queue这三种容器适配器, 来详细阐释容器适配器这种设计模式。

2. stack和queue

C++ stl中stack和queue在底层都是复用deque来实现的。

以下对deque进行简单的介绍。

2.1 deque

我们知道,list 的优点在于任意位置插入和删除数据,缺点则是每次插入都需要去申请资源(new的耗费是极大的);vector的优点在于支持下标的随机访问,缺点是insert和erase需要挪动数据,耗费很大。

通过上述分析,我们可以看到两种容器各有优缺点,于是有人就想,能不能综合一下两者的优点,设计出一种更好的容器呢?所以,deque应运而生,但现在来看,deque的设计并不能说是成功的。

2.1.1 deque的底层结构

deque的底层结构相对而言,还是比较复杂的。
它的底层并非一段连续空间,而是多段较小连续空间,有点类似动态的二维数组。所以,双端队列的底层实际是分段连续的。

双端队列的底层结构如下图所示:

在这里插入图片描述
结合下图,能更好地理解:

在这里插入图片描述
具体的说明如下:

  1. 双端队列的核心在于其底层的中控数组map。map实质上是一个指针数组,其中每个指针都指向一段连续空间的开始位置。
  2. 双端队列的迭代器设计也很特殊。它的迭代器中有四个成员变量——first指向某段连续空间的开始位置,last指向这段连续空间的结束位置,cur为当前连续空间遍历到的位置,node则是指向map中的某个位置,所以实际上node是一个二级指针。
  3. 通过迭代器和中控器,既能将某段连续空间管理好,同时又能便捷切换到下一段连续空间, 这样就将实际分段的连续空间虚拟地连续在了一起。
    在这里插入图片描述
    在这里插入图片描述

实际使用时,last可由first计算得来,因为每一段连续空间中存储的数据个数是规定好的,再结合具体的数据类型,即可由first计算出last。

刚开始使用时,deque中只有一段连续的空间,随着数据不断插入,当cur == last时,便会再申请一段连续的空间,然后通过node,将first,last,cur都切换到这段新申请的连续空间上(node一般指向中控数组中,当前这段空间起始位置所对应的指针,故 node + 1 对应新开辟的连续空间起始位置所对应的指针)。

不过,中控数组也是有一定大小的,所以当中控数组满容后,也是需要扩容的,这个扩容是正常的数组扩容。

2.1.2 deque如何实现头插和随机访问

在这里插入图片描述

deque的头插,需要再开一段连续的空间,然后将start中的first指向这段空间的开始,last指向这段空间的结束,cur指向这段空间最后一个元素的位置,再将node - 1赋值给node。
在这样的设计下,每次头插都要 cur-- ,而这段空间的终止条件则为 cur != first,与尾插刚好相反,但实现了头插的空间复杂度为O(1)。

在这里插入图片描述

那么,如何实现随机访问呢?

这要分两种情况来讨论:

  1. 如果没有头插或者因头插开辟的数组为满。记下标为 i ,记每段连续空间的元素个数为buffer_size那么通过 i / buffer_size来确定在第几段连续空间,通过 i % buffer_size来确定是那段连续空间的哪个位置,这样就能正常访问到相应元素。
  2. 如果头插开辟的数组未满。那么将下标i更换成,头插开辟的数组满时对应的下标,即 i 需要加上一个此数组中还能插入的元素个数,这样就能将 i 按照情况1中进行处理,从而访问到相应元素。

2.2 用deque实现栈和队列

此处不过多赘述,栈和队列的相关接口都是复用deque的接口以实现的。

在这里插入图片描述

在这里插入图片描述

2.3 deque的优缺点

其实,博主个人认为deque不能说是vector与list的综合,本身deque就是一个不成功的缝合怪,个人觉得,deque更像是对vector的优化——能够实现下标随机访问,同时头插相比vector的效率更高,也没有像vector那样,2倍或1.5倍扩容,因此浪费空间较少,但是deque仍然没有实现高效率的任意位置的插入和删除(仍然需要挪动数据),并不具备list那样的优势。

3. priority_queue

priority_queue,即优先队列,也是容器适配器,利用vector的相关接口来实现的。

什么是优先队列呢?正常的队列,是先进先出结构;而优先队列,不管入队顺序,统一按照一定的顺序,先出优先级高的,再出优先级低的。

所以,优先级队列本质上就是一个堆结构。

在这里插入图片描述

优先级队列的参数中还涉及一个仿函数的概念。
仿函数其实就是一个类,重载了operator() 这个运算符,因此使用起来就像一个函数一样,故得名仿函数。

优先级队列中仿函数的使用,是其常见的一个应用:用仿函数来自行控制大小比较的逻辑。
在优先级队列中,如果不使用仿函数,那么就需要写两个类模板,一个对应大堆,一个对应小堆,引入仿函数,那么写一个类模板即可。

以下是两个仿函数的示例:

在这里插入图片描述

值得一提的是,stl 中的优先级队列,默认建的是大堆。

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

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

相关文章

DeepSeek R1本地部署解决,DeepSeek服务繁忙

DeepSeek 本地部署是指将DeepSeek模型下载到本地电脑上,利用电脑的显卡进行数据处理和推理,可以减少网络延迟,提高数据处理和响应速度,从而避免将数据传输到云端,增强了数据的主权和控制,减少了因网络连接可…

GPT和BERT

笔记来源: Transformer、GPT、BERT,预训练语言模型的前世今生(目录) - B站-水论文的程序猿 - 博客园 ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频(RNN模型与NLP应用) 一、GPT 1.1 GPT 模型的…

深入浅出Java反射:掌握动态编程的艺术

小程一言反射何为反射反射核心类反射的基本使用获取Class对象创建对象调用方法访问字段 示例程序应用场景优缺点分析优点缺点 注意 再深入一些反射与泛型反射与注解反射与动态代理反射与类加载器 结语 小程一言 本专栏是对Java知识点的总结。在学习Java的过程中,学习…

JDK 14,15,17的一些新特性(部分常用)

1:instanceof(后,使用不再需要墙转) 2:switch语句增强 1:支持lmbda,自动防击穿,有返回值 2:支持case多个值,复杂逻辑结果支持yield返回 3:字符串…

活字格使用说明书

字格设计使用说明书 目录 1. 数据 2. 页面 3. 组件 4. 命令 一、数据 1.表数据创建(鼠标移动到表右击点击创建表) ‘ 图表 1 鼠标移至表1右击可重命名,添加字段输入所需字段名(一般数据类型的要注意:日期格式字段---日期、ID或者字典字段---整数、金…

springboot021校园周边美食探索及分享平台

版权声明 所有作品均为本人原创,提供参考学习使用,如需要源码数据库配套文档请移步 www.taobysj.com 搜索获取 技术实现 开发语言:Javavue。 框架:后端spingboot前端vue。 模式:B/S。 数据库:mysql。 开…

Kubernetes部署KeyDB服务

Kubernetes YAML 配置文件,部署一个 KeyDB 容器 vi keydb-deployment.yaml内容如下 apiVersion: apps/v1 kind: Deployment metadata:name: keydb-deployment spec:replicas: 1selector:matchLabels:app: keydbtemplate:metadata:labels:app: keydbspec:container…

新手自学:如何用gromacs对简单分子复合物进行伞形采样

1、建立体系: 1、将蛋白的pdb文件转化为gmx: gmx pdb2gmx -f 2BEG_model1_capped.pdb -ignh -ter -o complex.gro 这个网页可以实现将多肽序列转化为pdb: ProBuilder On-line 这个教程的蛋白2BFG包含两条链(chain A和B) 在生成的topol文件中,增加如下的内容,效果就…

如何使用Java语言在Idea和Android中分别建立服务端和客户端实现局域网聊天

手把手教你用Java语言在Idea和Android中分别建立服务端和客户端实现局域网聊天 目录 文章目录 手把手教你用**Java**语言在**Idea**和**Android**中分别建立**服务端**和**客户端**实现局域网聊天**目录**[toc]**基本实现****问题分析****服务端**Idea:结构预览Server类代码解…

金蝶云星空与马帮平台无缝对接,提高供应链效率

采购退货金蝶》马帮ok:系统对接集成案例分享 在企业的供应链管理中,数据的高效流转和准确处理至关重要。本文将聚焦于一个实际运行的系统对接集成案例——将金蝶云星空的数据集成到马帮平台,以实现采购退货数据的无缝传输和处理。 为了确保…

GPT-4o微调SFT及强化学习DPO数据集构建

假设,已经标注的训练数据集df包含了提示词、输入和输出三列。 构建微调SFT的数据集代码如下: data [] for x in df.values:prompt x[1]user_content x[2]assistant_content x[3]data.append({"messages": [{"role": "sys…

鸿蒙HarmonyOS NEXT开发:横竖屏切换开发实践

文章目录 一、概述二、窗口旋转说明1、配置module.json5的orientation字段2、调用窗口的setPreferredOrientation方法 四、性能优化1、使用自定义组件冻结2、对图片使用autoResize3、排查一些耗时操作 四、常见场景示例1、视频类应用横竖屏开发2、游戏类应用横屏开发 五、其他常…

02.10 TCP之文件传输

1.思维导图 2.作业 服务器代码&#xff1a; #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> …

Qt 控件整理 —— 按钮类

一、PushButton 1. 介绍 在Qt中最常见的就是按钮&#xff0c;它的继承关系如下&#xff1a; 2. 常用属性 3. 例子 我们之前写过一个例子&#xff0c;根据上下左右的按钮去操控一个按钮&#xff0c;当时只是做了一些比较粗糙的去演示信号和槽是这么连接的&#xff0c;这次我们…

1.Excel:某停车场计划调整收费标准❗(13)

目录 函数VLOOKUP ROUNDUP/ROUNDDOWN函数 NO1​ NO2会计专用类型​ NO3收费标准VLOOKUP​ NO4停放时间&#xff08;天&#xff09;​ NO5金额roundup/rounddown​ ​NO6汇总行​ NO7单元格突出显示​ NO8数据透视表​ 函数VLOOKUP VLOOKUP(收费标准!A3:B5 F4&#xf…

玩转大语言模型——使用Kiln AI可视化环境进行大语言模型微调数据合成

系列文章目录 玩转大语言模型——使用langchain和Ollama本地部署大语言模型 玩转大语言模型——三分钟教你用langchain提示词工程获得猫娘女友 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型—…

OpenAI推出的Computer Use智能体:Operator是什么

OpenAI推出的Computer Use智能体:Operator是什么 是一款能像人一样与图形用户界面交互来操作计算机的AI智能体。以下是其核心原理及举例说明: 核心原理 感知: 屏幕截图获取:利用高性能屏幕捕获模块,如基于WebRTC的截图技术,以极低延迟获取高清晰度页面图像,为后续分析…

k8s部署logstash

1. 编写logstash.yaml配置文件 --- apiVersion: v1 kind: Service metadata:name: logstash spec:type: ClusterIPclusterIP: Noneports:- name: logstash-tcpport: 5000targetPort: 5000- name: logstash-beatsport: 5044targetPort: 5044- name: logstash-apiport: 9600targ…

【AI大模型】Ollama部署本地大模型DeepSeek-R1,交互界面Open-WebUI,RagFlow构建私有知识库

文章目录 DeepSeek介绍公司背景核心技术产品与服务应用场景优势与特点访问与体验各个DeepSeek-R系列模型的硬件需求和适用场景 Ollama主要特点优势应用场景安装和使用配置环境变量总结 安装open-webui下载和安装docker desktop配置镜像源安装open-webui运行和使用 RagFlow介绍主…

【办公】钉钉修改默认存储位置,释放C盘空间

Step1: 右击钉钉图标选择设置 Step2: 通用里面找到文件保存位置&#xff0c;修改文件目录: 最新版本钉钉界面&#xff1a; 设置完成后按提示重启即可&#xff01;