当前位置: 首页 > news >正文

【C++】STL之适配器---用deque实现栈和队列

目录

前言

一、deque

 1、deque 的原理介绍

 2、deque 的底层结构

 3、deque 的迭代器

 4、deque 的优缺点

  4.1、优点

  4.2、缺点

二、stack 的介绍和使用

 1、stack 的介绍

 2、stack 的使用

 3、stack 的模拟实现

三、queue 的介绍和使用

 1、queue 的介绍 

 2、queue 的使用

 3、queue 的模拟实现


前言

  容器适配器,按字面意思理解的话,就是用来对一个容器进行匹配的。在C++STL中,容器有:vector,list,deque,map,set等。而在C++STL中不把stack和queue纳入容器的范围而是纳入容器适配器的范围是因为:

  stack和queue没有下标随机访问等操作,只有普通的pop_front,push_back,pop_back()等操作,而这些函数在其他容器中完全可以有,栈和队列的实现完全可以将其他容器的操作进行复用,这就是stack和queue作为容器适配器的原因。

  适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

一、deque

 1、deque 的原理介绍

  deque (双端队列):是一种双开口的 “连续” 空间的数据结构,双开口的含义是 deque 可以在头尾两端进行插入和删除操作,且时间复杂度为O(1);与vector比较,头插效率高,不需要搬移元素,与 list 比较,空间利用率比较高,“随机访问” 效率较高。

 2、deque 的底层结构

  deque 的底层结构其实并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际 deque 类似于一个动态的二维数组,其结构示意图如下:

 3、deque 的迭代器

  双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落 在了deque的迭代器身上,因此 deque 的迭代器设计就比较复杂,如下图所示:

 4、deque 的优缺点

  4.1、优点

  • 具有 vector 的优点 ---支持随机访问、缓存命中率较高、尾部插入删除数据效率高;
  • 同时具有 list 的优点 --- 空间浪费少、头部插入插入数据效率高;

  4.2、缺点

  • deque 的随机访问效率较低 --- 需要先通过中控数据找到对应的buffer数组,再找到具体的位置 (假设偏移量为 i,需先 i/10 得到位于第几个buffer数组,再 i%10 得到 buffer 数组中的具体位置),即 deque 随机访问时一次跳过一个buffer数组,需要跳多次才能准确定位,其效率比 list 高了不少,但比 vector 也低了不少;
  • deque 在中部插入删除数据的效率是比较低的 --- 需要挪动数据,但不一定后续 buffe 数组中的数据全部挪动,可以控制只挪一部分,即中间插入删除数据的效率高于 vector,但是低于 list。

 所以综上分析, deque 结合了 vector 和 list 的优缺点,看似很完美,但是它单方面的性能是不如 vector 或者 list 的,因此 deque 在实际应用中使用的非常少。

STL 中选择 deque 作为 stack 和 queue 默认适配容器的原因:

  • stack 和 queue 不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
  • 在 stack 中元素增长时,deque 比 vector 的效率高(扩容时不需要搬移大量数据);queue 中的元素增长时,deque不仅效率高,而且内存使用率高。

结合了deque的优点,而完美的避开了其缺陷。

  deque 特别适合需要大量进行头插和尾部数据的插入删除、偶尔随机访问、偶尔中部插入删除的场景;不太适合需要大量进行随机访问与中部数据插入删除的场景,特别是排序。

二、stack 的介绍和使用

 1、stack 的介绍

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定 的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
  3. stack 的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:empty:判空操作 back:获取尾部元素操作 push_back:尾部插入元素操作 pop_back:尾部删除元素操作;
  4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器, 默认情况下使用deque。

 2、stack 的使用

函数说明接口说明
stack()构造空的栈
empty()检测 stack 是否为空
size()返回 stack 中元素的个数
top()返回栈顶元素的引用
push()将元素 val 压入 stack 中
pop()将 stack 中尾部的元素弹出

下面是栈的使用操作: 

int main()
{//构造空栈stack<int> s;//元素入栈s.push(1);s.push(2);//获取栈中元素个数int Size = s.size();cout << Size << endl;//获取栈顶元素的引用int sTop = s.top();cout << sTop << endl;//元素出栈s.pop();sTop = s.top();cout << sTop << endl;//判断栈是否为空cout << s.empty();return 0;
}

 3、stack 的模拟实现

  我们在这里为栈模板定义了两个模板参数:是栈中存储的元素的类型Container 是栈模板使用的底层结构Container 的默认值是 vector,如果你想要用别的,可以在这里进行设置。我就可以将适配器作为类的第二个模板参数,然后通过传递不同的适配容器来实现栈了:

//stack.h
template<class T, class Container>
class stack 
{//...
};
//test.cpp
void test_stack() 
{stack<int, vector<int>> st1;stack<int, list<int>> st2;
}

vector 和 list 都可以作为 stack 的适配容器,我们可以通过给定不同的第二个模板参数来使用不同的容器适配 stack;

 经过前期的学习,显然更适合作为 stack 的适配容器,那么我们可以还可以将 vector 设置为 stack 的默认适配容器:

//stack.h
template<class T, class Container = vector<T>>
class stack 
{//...
};
//test.cpp
void test_stack() 
{//默认使用vector做适配容器stack<int> st1;  //使用其他容器做适配容器需要显式指定stack<int, list<int>> st2;  
}

 有了适配容器之后,我们就可以更容易的通过调用适配容器的接口来实现 stack 的接口了。

namespace xx
{//适配器模式/配接器template <class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}bool size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};void test_stack(){//stack<int,vector<int>> st;//数组栈stack<int, list<int>> st;//链表栈st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;}
}

stack 可以使用 vector 或者 list 来实现,效率相当。插入数据就相当于尾插,删除栈顶元素就相当于尾删。

三、queue 的介绍和使用

 1、queue 的介绍 

  1. 队列是一种容器适配器,专门用于在 FIFO 上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。
  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue 提供一组特定的 成员函数来访问其元素。元素从队尾入队列,从队头出队列。
  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作: empty:检测队列是否为空 ; size:返回队列中有效元素的个数; front:返回队头元素的引用;back:返回队尾元素的引用;push_back:在队列尾部入队列;pop_front:在队列头部出队列;
  4. 标准容器类 deque 和 list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标准容器 deque。

 2、queue 的使用

函数声明接口说明
queue()构造空的队列
empty()检测队列是否为空,是返回 true,否则返回 false
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素 val 入队列
pop()将队头元素出队列

下面是队列的使用操作:

int main() 
{//构造空队列queue<int> q;//元素入队q.push(1);q.push(2);//返回有效元素个数int size = q.size();cout << size << endl;//检查队列是否为空cout << q.empty() << endl;//获取队头元素的引用int front = q.front();cout << front << endl;//获取队尾元素的引用 int back = q.back();cout << back << endl;//队头元素出队q.pop();return 0;
}

 3、queue 的模拟实现

  它的模拟实现过程和 stack 类似,vector 和 list 都可以作为 queue 的适配容器,但是由于 queue 需要大量在头部删除数据,所以使用 deque 作为 queue 的默认适配容器,那么 queue 模拟实现的代码如下:

namespace xx
{template <class T, class Container = deque<T>>class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}const T& front(){return _con.front();}const T& back(){return _con.back();}bool size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};void test_queue(){queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}
}


本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。

相关文章:

【C++】STL之适配器---用deque实现栈和队列

目录 前言 一、deque 1、deque 的原理介绍 2、deque 的底层结构 3、deque 的迭代器 4、deque 的优缺点 4.1、优点 4.2、缺点 二、stack 的介绍和使用 1、stack 的介绍 2、stack 的使用 3、stack 的模拟实现 三、queue 的介绍和使用 1、queue 的介绍 2、queue 的使用 3、qu…...

PHY6230低成本遥控灯控芯片国产蓝牙BLE5.2 2.4G SoC

高性价比的低功耗高性能蓝牙5.2系统级芯片&#xff0c;适用多种PC/手机外设连接场景。 高性能多模射频收发机&#xff1a; 通过硬件模块的充分复用实现高性能多模数字收发机。发射机&#xff0c;最大发射功率10dBm&#xff1b;BLE 1Mbps速率接收机灵敏度达到-96dBm&#xff1…...

OceanBase杨传辉传递亚运火炬:国产数据库为“智能亚运”提供稳稳支持

9 月 14 日&#xff0c;亚运火炬传递到了浙江台州&#xff0c;OceanBase 的 CTO 杨传辉作为火炬手交接了第 89 棒火炬。 2010 年&#xff0c;杨传辉作为创始成员之一参与自研原生分布式数据库 OceanBase。十年磨一剑&#xff0c;国产数据库 OceanBase 交出了一张优秀的成绩单&a…...

分布式锁实现方法

分布式锁 什么时候需要加锁 有并发&#xff0c;多线程有写操作有竞争关系 场景&#xff1a; 电商系统&#xff0c;下单流程&#xff1a;用户下单–>秒杀系统检查redis商品库存信息–>用户锁定并更新库存&#xff08;mysql&#xff09;—>秒杀系统更新redis 问题&…...

软件测试缺陷报告详解

【软件测试行业现状】2023年了你还敢学软件测试&#xff1f;未来已寄..测试人该何去何从&#xff1f;【自动化测试、测试开发、性能测试】 缺陷报告是描述软件缺陷现象和重现步骤地集合。软件缺陷报告Software Bug Report&#xff08;SBR&#xff09;或软件问题报告Software Pr…...

pytorch冻结参数训练的坑

由于项目需要训练一个主干网络接多个分支的模型&#xff0c;所以先训练一个主干网络加第一个分支&#xff0c;再用另外的数据训练第二个分支&#xff0c;训练的过程中需要冻结主干网络部分&#xff0c;后面的分支训练过程也一样需要冻结主干网络部分。 冻结模型的方式 for nam…...

P1827 [USACO3.4] 美国血统 American Heritage(前序 + 中序 生成后序)

P1827 [USACO3.4] 美国血统 American Heritage&#xff08;前序 中序 生成后序&#xff09; 一、前言 二叉树入门题。涉及到树的基本知识、树的结构、树的生成。 本文从会从结构&#xff0c;到完成到&#xff0c;优化。 二、基础知识 Ⅰ、二叉树的遍历 前序遍历&#xff…...

【四、centOS安装docker】

安装docker sudo yum install -y yum-utils device-mapper-persistent-data lvm2 如果以上报错 备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup进入 /etc/yum.repos.d cd /etc/yum.repos.d删除文件 rm -f *.r…...

想学嵌入式开发,薪资怎么样?

想学嵌入式开发&#xff0c;薪资怎么样&#xff1f; 对于嵌入式工程师来说呢&#xff0c;它重点学习内容就是首先一定要打好基础&#xff0c;如果从编程语言角度来讲&#xff0c;那么可以在语言上选C或者C&#xff0c;你可以选择其中任何一门语言作为你的入门。 最近很多小伙伴…...

SQL死锁进程内容查询语句

1.方式1 SELECT object_name(A.resource_associated_entity_id) as TABLENAME, A.request_session_id AS SPID,DB_NAME(B.dbid) AS DBName,B.blocked,B.dbid,B.program_name,B.waitresource,B.lastwaittype,B.loginame,B.hostname,B.login_time,B.last_batch--,B.* FROM sy…...

Ubuntu 20.04中Nightingale二进制部署

参考博客《【夜莺监控】初识夜莺&#xff0c;强&#xff01;》 lsb_release -r可以看到操作系统版本是20.04&#xff0c;uname -r可以看到内核版本是5.5.19。 sudo apt-get update进行更新镜像源。 完成之后&#xff0c;如下图&#xff1a; sudo apt-get upgrade更新软件…...

深入探讨Java面试中内存泄漏:如何识别、预防和解决

引言 在编写和维护Java应用程序时&#xff0c;内存泄漏是一个重要的问题&#xff0c;可能导致性能下降和不稳定性。本文将介绍内存泄漏的概念&#xff0c;为什么它在Java应用程序中如此重要&#xff0c;并明确本文的目标&#xff0c;即识别、预防和解决内存泄漏问题。 内存泄…...

win10 安装.net framework 3.5,错误代码0x8024401C

win10 安装.net framework 3.5&#xff0c;错误代码0x8024401C 参考链接&#xff1a;https://www.gxlsystem.com/diannaowenti-386775.html 解决方法如下&#xff0c;cmd中执行&#xff1a; net stop wuauserv reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W…...

杂记 | Langchain中few-shot提示词模板的使用(给提示词添加示例)

文章目录 01 普通的提示词模板02 few-shot提示词模板 Langchain是一个集成多个大语言模型的开源框架&#xff0c;可以使用它来快速开发大语言模型应用。 本文的代码使用到的模块&#xff1a; from typing import List, Dict from langchain import PromptTemplate, FewShotPr…...

SVN -基础

SVN - 基础 概念操作步骤开发实际经验 概念 带SVN路径 有隐藏文件&#xff0c;记录repo的一些信息&#xff0c;与repo进行关联&#xff0c;可以与repo进行同步 不带SVN路径 只是单纯的文件&#xff0c;与repo独立 操作步骤 checkout 具有路径 URLcheckout dir 输出目标文件夹…...

MySQL基础终端命令与Python简单操作MySQL

文章目录 MySQL终端命令1. 进入mysql2. 创建数据库3. 选择数据库4. 创建数据表1. 主键约束2. 外键约束3. 非空约束4. 唯一约束5. 使用默认约束6. 设置id为自增列 5. 查看数据表6. 修改数据表1. 修改表名2. 修改表的字段类型3. 修改表的字段名4. 为表添加字段5. 删除字段6. 调整…...

编译原理.龙书学习1

第一章&#xff1a; 编译器&#xff1a;将程序翻译成一种能够被计算机执行的形式 解释器&#xff1a;解释器直接利用用户提供的输入执行源程序中指定的操作 一个编译器的结构 编译器将源程序映射为语义上等价的目标程序&#xff0c;这个映射过程由两部分组成&#xff1a;分析…...

anaconda安装完成之后输入conda -V没有反应

anaconda安装完成后&#xff0c;conda没有反应 vim ~/.bashrc后面添加内容 # added by Anaconda3 5.3.0 installer # >>> conda init >>> # !! Contents within this block are managed by conda init !! __conda_setup"$(CONDA_REPORT_ERRORSfalse /u…...

netty报文解析之粘包半包问题

粘包问题 Netty 的粘包问题是指在网络传输过程中&#xff0c;由于 TCP 协议本身的特点&#xff0c;导致发送方发送的若干个小数据包被接收方合并成了一个大数据包。这种情况称为粘包。 TCP 协议是面向流的协议&#xff0c;没有数据边界&#xff0c;发送方发送的数据可能会被分…...

EasyCode整合mybatis-plus的配置

文章目录 entitymapper.javamapper.xmlserviceserviceImplcontroller 这篇文章不教你如何安装和使用EasyCode&#xff0c;只是贴出可以使用的配置。 具体EasyCode的使用可以查看其它的文章。 entity ##导入宏定义 $!{define.vm}##保存文件&#xff08;宏定义&#xff09; #sa…...

实施预测性维护解决方案的挑战及PreMaint的应对方法

前面我们介绍了企业选择预测性维护解决方案的常见问题和PreMaint的策略&#xff0c;本期我们将带来实施过程中可能会遇到的挑战&#xff0c;以及如何通过PreMaint来应对这些挑战&#xff0c;以实现可靠的预测性维护。 随着工业技术的不断进步&#xff0c;预测性维护作为一种先进…...

1. js中let、var、const定义变量区别与方式

1 声明语法 var upperA A; let upperB B; const upperC C; 只声明不初始化的结果&#xff0c;【 const定义的常量不可以修改&#xff0c;而且必须初始化】 // var 声明变量 var upperA; console.log(打印大写的A&#xff1a;%s, upperA); // 结果&#xff1a;打印大写的A&am…...

【STM32学习】I2C通信协议 | OLED屏

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《STM32学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 今天需要将代码烧录到开发板中&#xff0c;本喵默认大家都会创建工程&#xff0c;以及进行基本的…...

Nvme Spec 第一章节学习

Nvme Express Base Specification 第一章 简介 1.1概述 NVM ExpressTM&#xff08;NVMeTM&#xff09;接口允许主机软件与非易失性存储器子系统通信。 此接口针对企业和客户端固态驱动器进行了优化&#xff0c;通常作为寄存器级接口连接到PCI Express接口。 注&#xff1a;在…...

第一章:最新版零基础学习 PYTHON 教程(第九节 - Python 语句中的 – 多行语句)

Python 中的语句: 在Python中,语句是Python解释器可以读取和执行的逻辑命令。它可能是Python 中的赋值语句或表达式。 Python 中的多行语句: 在Python中,语句通常写成一行,每行的最后一个字符是换行符。要将语句扩展到一行或多行,我们可以使用大括号 {}、圆括号 ()、方…...

kafka 3.0 离线安装

1.安装zookeeper 解压apache-zookeeper-3.8.0-bin.tar.gz到指定目录,复制conf目录下zoo_sample.cfg到zoo.cfg,并修改配置。 # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit…...

MySQL数据库入门到精通2--基础篇(函数,约束,多表查询,事务)

3. 函数 函数 是指一段可以直接被另一段程序调用的程序或代码。MySQL中的函数主要分为以下四类&#xff1a; 字符串函数、数值函数、日期函数、流程函数。 3.1 字符串函数 MySQL中内置了很多字符串函数&#xff0c;常用的几个如下&#xff1a; 演示如下&#xff1a; A. con…...

c-数据在内存中的存储-day7

...

3D大模型如何轻量化?试试HOOPS Communicator,轻松读取10G超大模型!

随着计算机技术的不断发展&#xff0c;3D模型在各行各业中的应用越来越广泛。然而&#xff0c;随着模型的复杂性和规模不断增加&#xff0c;处理和浏览超大型3D模型变得越来越具有挑战性。本文将探讨如何轻量化3D大模型&#xff0c;以及如何使用HOOPS Communicator来读取和浏览…...

go并发操作且限制数量

使用管道chan func returnNum() int64 {return time.Now().Unix() } func main() {threadAmount : runtime.GOMAXPROCS(0)if threadAmount < 2 {threadAmount 2}fmt.Println(threadAmount)threadChan : make(chan int, threadAmount)defer close(threadChan)for {for i :…...

一个网站的开发周期/最有效的恶意点击软件

RedHat Linux 6.2下Oracle10g安装配置手册以下都是root用户操作1. 安装准备1.1 RedHatLinux Server 6.2安装文件RatHatLinuxServer-6.2-x86_64.iso1.2 Oracle10g Linux安装文件10201_database_linux_x86_64.cpio.gz1.3 检查安装包rpm -qa |grep makeautomake-1.11.1-1.2.el6.n…...

三明网站制作/seo优化软件免费

安装1、手动下载MyBatisGenerator插件提取码&#xff1a;u2gs2、在Myclispse安装目录\MyEclipse 2017 CI\dropins下创建myBatisgenerator文件夹3、将插件压缩包中的两个文件夹移动到mybatisgenerator文件夹中4、启动MyElicpse&#xff0c;选择File-New-Other&#xff0c;出现下…...

wordpress修改头部显示/青岛做网站推广

为什么80%的码农都做不了架构师&#xff1f;>>> MongoDB 1. 概念 SQL 与 NoSQL(MongoDB)的对比 关系型数据库 MongoDB 数据库 数据库 表 Table 集合 Collection 行 Row/Tuple 文档 Document 列 Column 字段 Field 表 Join 内嵌文档 Embedded Documen…...

王爷你的王妃有毒全文免费阅读/乐天seo培训

如果你从Python解释器中退出&#xff0c;并且再次进入&#xff0c;你会发现你以前定义的函数和变量都已经丢失了。所以&#xff0c;如果你想写一个在某种程度上更长的程序&#xff0c;使用一个文本编辑器来准备解释器的输入会使情况有所好转&#xff0c;并且使用文件代替输入来…...

网页设计尺寸厘米/深圳有实力的seo公司

因为组播中的组地址是虚拟的&#xff0c;所以不可能如同单播那样&#xff0c;直接从数据源一端路由到特定的目的地址。组播应用程序将数据包发送给一组希望接收数据的接收者&#xff08;组播地址&#xff09;&#xff0c;而不是仅仅传送给一个接收者&#xff08;单播地址&#…...

政府门户网站集约化建设的探索/重庆seo公司排名

林炳文Evankaka 原创作品。转载请注明出处 http://blog.csdn.net/evankaka摘要&#xff1a;本文将使用Python3.4爬网页、爬图片、自动登录。并对HTTP协议做了一个简单的介绍。在进行爬虫之前&#xff0c;先简单来进行一个HTTP协议的讲解&#xff0c;这样下面再来进行爬虫就是理…...