【C++】详解STL容器之一的deque和适配器stack,queue

目录

deque的概述

deque空间的结构

deque的迭代器

deque的数据设计

deque的优缺点

适配器的概念

​编辑

stack的概述

stack的模拟实现

queue的概述

queue的模拟实现


deque的概述

deque的设计参考了另外两大容器vectorlist。可参考下面两篇文章

详解vector:http://t.csdnimg.cn/19TWM

详解list:http://t.csdnimg.cn/2rCbL

vector容器管理的是线性空间,vector的容器是单向开口。这说明vector的容器的头部插入,头部删除的时间效率是O(N),尾部插入,尾部删除的效率是O(1)。

与之相对的deque所管理的空间也可以看作是线性空间。deque的线性空间是双向开口。这说明deque容器的头部插入,头部删除,尾部插入,尾部删除的效率是O(1)

deque管理的空间不够时,不需要像vector那样成倍的扩容。此时,管理一段线性空间的deque却能像list的那样一小段一小段的扩容,并且还能保证自己管理的依旧是一段线性空间。

既然deque管理的是一段线性的空间,那一定支持随机访问,那么在deque的容器中排序的效率怎么样呢?实际上,在deque容器中的排序效率并不理想,在一亿这个数据量级,用deque容器排序的用时是用vector容器排序用时的五倍。现在给出如下两个方案,方案一:直接用deque排序。方案二:把deque容器中的数据拷贝给vector,让vector排序,再把排好的数据拷贝给deque。方案一的效率也远远的不如方案二。

从排序的效率中可以看出,deque容器管理的线性空间是一种假象

deque空间的结构

deque会开一小段空间存数据,如果空间不够,会再开一小段相等大小的空间,这一小段空间称为缓冲区这些缓冲区的才是deque容器存数据的空间而这些一小段一小段的空间的指针会按一定顺序存入一段名为map的连续的空间,map就是管理所有缓冲区的中控器,如下图

如下是源码定义

template <class T, class Alloc = alloc, size_t BufSize = 0>
class deque
{
public:
typedef T value_type;
typedef value_type* pointer;//......
protected:
typedef pointer* map_pointer;  //指向数据的指针protected:
map_pointer map; //储存指针空间的map,本质是个二级指针,map指向的连续的空间size_t map_size; //map可容纳指针的个数
}

deque的迭代器

要让如此复杂的空间关系在上层表现的像线性空间一样,需要设计一个很复杂的迭代器。源码的迭代器封装了四个指针。

T* cur; 用来遍历缓冲区,也可以用来数据的存取

T* first; 指向缓冲区的头

T* last; 指向缓冲区的尾

map_pointer node; 指向中控器的指针,被指向的指针又指向该缓冲区

用如此复杂的迭代器想要随机访问数据是要付出代价的,因为缓冲区在内存中是不连续的,想要从一个缓冲区去下一个缓冲区,必须通过迭代器的node指针在中控器的空间上偏移实现。这便是用deque容器排序效率不高的原因。

deque的数据设计

iterator start; 用一个迭代器指向第一个缓冲区

iterator finish; 用一个迭代器指向最后一个缓冲区

map_pointer map; 指向中控器,方便管理中控器

size_type map_size; 中控器中有多少指针


deque的优缺点

总结一下deque容器的优缺点

 deque优点: 

与vector比较,头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不 需要搬移大量的元素,头插头删,尾插尾删的效率很高
与list比较,其底层是连续空间,空间利用率比list较高,不需要存储额外字段。缓存命中率比list高
deque缺点:
与vector比较deque不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到
某段小空间的边界,导致效率低下,因此用deque容器排序的效率也是低下的

与list比较:deque不适合在中间插入数据,因为需要挪动数据。而list只需改变指向关系即可。

vector和list都有很明显的优点和很明显的缺点,deque就好像夹在vector和list中间的容器,找不到很亮眼的优点。

适配器的概念

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。
虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配
器,这是因为stack和queue只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque,比如:

STL在实现stack, queue时,并没有再去设计一个容器,而是直接复用其他容器,这便是适配器。这是一种设计思想


stack的概述

stack别名为,栈是一种先进后出的数据结构。栈只有一个开口,只能从这个开口入数据和出数据。

栈没有迭代器,这说明栈是不允许遍历的

栈的底层可以适配vector容器,list容器,deque容器,默认适配deque容器

stack的模拟实现

#include<vector>
#include<list>
#include<deque>namespace bit
{// template<class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};

queue的概述

dueue别名为队列,队列是一种先进先出的数据结构。队列只能队尾如数据,队头出数据。

队列没有迭代器,这说明队列是不允许遍历的

队列的底层可以适配list容器,deque容器,默认适配deque容器


queue的模拟实现

#include<vector>
#include<list>
#include<deque>namespace bit
{// template<class T, class Container = deque<T>>class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();//_con.erase(_con.begin());}T& front(){return _con.front();}T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};

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

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

相关文章

Spring Boot 整合 socket 实现简单聊天

来看一下实现的界面效果 pom.xml的maven依赖 <!-- 引入 socket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- 引入 Fastjson &#x…

bert-NER 转化成 onnx 模型

保存模型 加载模型 from transformers import AutoTokenizer, AutoModel, AutoConfigNER_MODEL_PATH ./save_model ner_tokenizer AutoTokenizer.from_pretrained(NER_MODEL_PATH) ner_config AutoConfig.from_pretrained(NER_MODEL_PATH) ner_model AutoModelForTokenCl…

【雅思写作】Vince9120雅思小作文笔记——P1 Intro(前言)

文章目录 链接P1 Intro&#xff08;前言&#xff09;字数限制题型综述&#xff08;problem types overview&#xff09;1. **柱状图&#xff08;Bar Chart&#xff09;** - 描述不同类别在某个或多个变量上的数据量比较。2. **线图&#xff08;Line Graph&#xff09;** - 展示…

冯喜运:5.10黄金反弹受阻,原油EIA库存激增引发市场情绪

【黄金消息面分析】&#xff1a;据最新市场数据显示&#xff0c;现货黄金在周四欧市早盘经历了显著下滑&#xff0c;价格一度跌破2310美元/盎司的关口&#xff0c;日内高点回落达10美元&#xff0c;截至发稿&#xff0c;黄金小幅反弹&#xff0c;交投于2312美元/盎司附近。此番…

【工具】如何提取一个mp4文件的关键帧

文章目录 怎么做如何安装ffmepgUbuntu 或 DebianCentOS 或 FedoramacOSWindows其他 Linux 发行版 实践什么是关键帧 怎么做 你可以使用ffmpeg这个强大的多媒体处理工具来提取mp4文件中的关键帧。以下是一个示例命令&#xff0c;可以使用ffmpeg从mp4文件中提取关键帧&#xff1…

即将开幕,邀您共赴创新之旅“2024上海国际消费者科技及创新展览会”

备受期待的2024上海国际消费者科技及创新展览会&#xff08;以下简称“CTIS”&#xff09;即将于6月13日至15日亮相上海新国际博览中心N1-N3馆。 2024上海国际消费者科技及创新展览会总面积达40,000平方米&#xff0c;涵盖600余家展商&#xff0c;预计吸引40,000多位观众莅临现…

单片机——直流电机

1 .关于4线直流电机 两根12v供电线&#xff0c;通入12v&#xff0c;风扇以最高转速工作。 一根测速线&#xff0c;电机工作时输出测速信号&#xff0c;提供转速反馈。一根PWM控制信号线&#xff0c;电机工作时控制器输入PWM控制信号&#xff0c;以控制风扇转速(通常为占空比可…

Python爬虫基础知识学习(以爬取某二手房数据、某博数据与某红薯(书)评论数据为例)

一、爬虫基础流程 爬虫的过程模块化&#xff0c;基本上可以归纳为以下几个步骤&#xff1a; 1、分析网页URL&#xff1a;打开你想要爬取数据的网站&#xff0c;然后寻找真实的页面数据URL地址&#xff1b; 2、请求网页数据&#xff1a;模拟请求网页数据&#xff0c;这里我们介…

双翻斗雨量计学习

双翻斗雨量计用户手册&#xff08;脉冲型&#xff09; 本仪器由雨量计壳体、承雨口、漏斗、翻斗支撑、上漏斗雨量调节支架、上漏斗、汇集漏斗、计数翻斗雨量调节支架、计数翻斗、干簧管安装架、轴承螺钉、出水漏斗、腿部支架、干簧管、水平泡、调节支撑板、控制盒、调平装置、接…

安装oh-my-zsh(命令行工具)

文章目录 一、安装zsh、git、wget二、安装运行脚本1、curl/wget下载2、手动下载 三、切换主题1、编辑配置文件2、切换主题 四、安装插件1、zsh-syntax-highlighting&#xff08;高亮语法错误&#xff09;2、zsh-autosuggestions&#xff08;自动补全&#xff09; 五、更多优化配…

MySQL#MySql表的操作

目录 一、创建表 二、查看表结构 三、修改表 1.修改表的名字 2.新增一个列 3.修改列 4.删除列 5.修改列的名称 四、删除表 一、创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校…

element-ui skeleton 组件源码分享

今日简单分享 skeleton 骨架屏组件源码&#xff0c;主要从以下四个方面来讲解&#xff1a; 1、skeleton 组件的页面结构 2、skeleton 组件的属性 3、skeleton item 组件的属性 4、skeleton 组件的 slot 一、skeleton 组件的页面结构 二、skeleton 组件的属性 2.1 animate…

漏洞管理是如何在攻击者之前识别漏洞从而帮助人们阻止攻击的

漏洞管理 是主动查找、评估和缓解组织 IT 环境中的安全漏洞、弱点、差距、错误配置和错误的过程。该过程通常扩展到整个 IT 环境&#xff0c;包括网络、应用程序、系统、基础设施、软件和第三方服务等。鉴于所涉及的高成本&#xff0c;组织根本无法承受网络攻击和数据泄露。如果…

JUC下的ForkJoinPool详解

详细介绍 ForkJoinPool 是 Java 并发包 (java.util.concurrent) 中的一个特殊线程池&#xff0c;专为分治算法设计&#xff0c;能够高效地处理大量可分解的并行任务。它基于工作窃取&#xff08;work-stealing&#xff09;算法&#xff0c;当一个工作线程的任务队列为空时&…

HFSS学习-day3-HFSS的工作界面

工作界面也称为用户界面&#xff0c;是HFSS软件使用者的工作环境:了解、熟悉这个工作环境是掌握HFSS软件使用的第一步 HFSS工作环境介绍 1.HFSS工作界面简单的组成说明2.工作界面中各个工作窗口功能主菜单工具栏项目管理窗口属性窗口信息管理窗口进程窗口三维模型窗口 3.HFSS主…

数据结构_栈和队列(Stack Queue)

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 栈&#xff1a; 代码&#xff1a;function/数据结构_栈/stack.c 钦某/c-language-learning - 码云 - 开源中国 (gitee.com)https://gitee.com/wang-qin928/c-language-learning/blob/master/function/…

java中的oop(三)、构造器、javabean、uml类图、this、继承

!! 有get/set方法的情况基本就是说要搞个私有属性&#xff0c;不直接对外开放&#xff1b; 构造器 Person p new Person(); //其中的Person();就是构造器&#xff1b;---造对象&#xff1b;Constructor–建设者&#xff0c;建造者&#xff1b; 作用 搭配new 创建类的&…

docker学习-docker常用其他命令整理

随便写写&#xff0c;后面有空再更新 镜像命令&#xff0c;容器命令已在之前略有更新&#xff0c;这次不写&#xff0c; 一、后台启动命令 # 命令 docker run -d 容器名 # 例子 docker run -d centos # 启动centos&#xff0c;使用后台方式启动 # 问题&#xff1a; 使用doc…

大数据手册(Spark)--Spark 简介

Spark 简介 Apache Spark 是一种用于大数据工作负载的分布式开源处理系统。它使用内存中缓存和优化的查询执行方式&#xff0c;可针对任何规模的数据进行快速分析查询。Apache Spark 提供了简明、一致的 Java、Scala、Python 和 R 应用程序编程接口 (API)。 Apache Spark 是专…

代码随想录第四十三天|最后一块石头的重量 II 、目标和

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a;