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

stack与queue的简单封装

    前言: stack与queue即栈和队列,先进后出/先进先出的特性我们早已了然于心,  在学习数据结构时,我们利用c语言实现栈与队列,从结构体写起,利用数组或指针表示他们的数据成员,之后再一个个实现他们的函数接口,简单来说我们是直接手撕栈和队列的。

但对于c++来说,c++提供了模板,提供了标准模板库,利用这些们只需要实现它的特性,然后再封装它即可。

在实现之前,我们再来了解一下何为适配器?

适配器

本质上是一种设计模式-适配器模式:

Adapter(适配器模式)属于结构型模式,结构性模式关注的是如何组合类与对象,以获得更大的结构,我们平常工作大部分时间都在与这种设计模式打交道。

意图:将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。
对于统一多个类的接口适配器模式就比较适用。

适配器, 在STL中扮演着转换器的角色,用于将一种接口转换成另一种接口,从而是原本不兼容的接口能够很好地一起运作。

容器、迭代器、和函数都有适配器,  适配器不提供迭代器。

栈的简单封装

一般对于我们自己来说实现一个栈,利用c++提供的STL我们可以直接封装,比如我们直接利用vector表示整个栈,出栈即尾删,入栈即尾插,获取栈顶元素即返回数组末尾元素,其他接口我们也不难实现:

template <class T>class stack      
{
public://栈的重要接口//入栈viod push(cosnt T& x){_container.push_back(x);//直接调用尾插}//出栈void pop(){_container.pop_back(x);//直接调用尾删}//获取栈顶元素const T& top(){return _container.back();//返回尾元素}//大小size_t size(){return _container.size();}//判空bool empty(){return _container.empty();}private://直接利用容器vector<T>> _container;};

 添加容器模板参数(适配器)

    对于栈我们知道本质是数组,那么直接调用数组模板即可,但对于栈的实现我们发现不仅仅直接利用数组,利用链表也是可以实现栈的,其次由于在设计标准模板库时根据泛型编程的思维,这使得接口其功能都是一样的()。

那么在实现栈的时候,不仅仅利用一种模板,而是多模板,这使得我们在设计实现栈时,可以提供一个容器模板(根据不同的容器也能实现栈),因此我们还添加了Container(容器模板),达到实现不同容器,统一接口的实现。

template <class T,class Container>class stack      
{
public://栈的重要接口//入栈void push(const T& x){_container.push_back(x);//直接调用尾插}//出栈void pop(){_container.pop_back();//直接调用尾删}//获取栈顶元素const T& top(){return _container.back();//返回尾元素}//大小size_t size(){return _container.size();}//判空bool empty(){return _container.empty();}const T& front(){return _container.front();}const T& back(){return _container.back();}
private://直接利用容器Container _container;};

  对于这里的容器模板,其实就是适配器,通过参数控制不同容器适配出同样效果的数据结构(感觉这也是泛型编程的特点,不追求底层,只看当前的功能)。

队列的简单封装

通过对栈的是实现,我们也可以利用适配器这种方式来实现队列,不过需要注意的是:

我们在选用容器的时候还是要应当注意容器是否满足我们在实现某个功能时,提供所需要的接口,对于队列,这里使用vector就不行了,并不能一股脑认为是个容器都可以。

template<class T, class Container = deque<T>>class queue
{
public://入队void push(const T& x){_con.push_back(x);}//出队void pop(){_con.pop_front();}void top(){return _con.front();}size_t size(){return _con.size();}const T& front(){return _con.front();}const T& back(){return _con.back();}bool empty(){return _con.empty();}
private:Container _con;};

库中的实现


  利用适配器我们可以将能实现的容器集合在一起,控制参数来控制容器,那么既然是参数,我们想这里也应该可以设置缺省参数的,那么缺省参数如何设置呢?我们可以看看库中的实现:

初识双端队列

库中这里设置的缺省参数是双端队列,我们可以看看双端队列:

 首先对于双端队列,我们不要认为他是一个队列,其次我们在观察它的接口:

双端队列,本质上是一个顺序表,可以看到它的接口与vector和list非常相似,从功能上来说,他是将vector与list的功能集合到一起,同时具有两种结构的接口(包括尾插,尾删,头插,头删,正反向迭代器,[ ]访问元素,插入,删除等接口),可以看到非常之牛,它好像同时满足了vector和list的所有优点:

1.vector的连续地址,支持快速访问。

2.list的高效率随机位置插入。

犹如六边形战士,那么真实情况果真如此吗?事实并非如此。

我们可以了解一下他的结构,因为能支持数组随机访问,且能随机插入,那么其空间应该是连续的,但不完全连续:

即利用指针,将各个数组连接起来,指针被存放在叫中控数组的地方,存放数据的叫做buffer数组。

迭代器设计:

 可以看到迭代器是由四个数据封装起来的,其中第一个位置的cur指向的是当前数组的第一个位置,第二个位置的first指向的是数组第一个位置,第三个last指向的是数组最后位置,二级指针node指向的是中控数组里的某个指针。

以这样的方式封装了begin与end这两个表示开头语结尾的迭代器。

        对于双端队列,它的数据插入是从中间开始的,如若头或尾某个地方的数据已经满了,那么他会新开一个buffer数组,将数组存放起来(头部插入,放数组后面,尾部插入放数组前面),再连接起来,当然如果数据够多使得中控数组都已经插入满了,那么需要扩容中控数组,不过代价会比较低,但是对于中间插入数据,如若中间的某个位置的buffer数组已经满了,那么有两种选择方案:

扩容或者挪动数据,如何选择看你的取舍:

若果是扩容的话,因为我们[ ]访问数据对于同样大的数组访问速度会比较快,我们可以很好的计算出它的位置从而访问它(比如我们对数组的大小取余或取整,就可以知道是某个数组的第几个),若扩容,则该位置访问是比较困难的。

如果是挪动数据的话,整体后挪数据,数据量太大,那么代价就非常大了,效率会特别低。

这样一看其实是对于双端队列,我们头插尾插数据时效率是比较高的,但对于中间插入数据实在是不太行啊,这也是为什么叫双端队列,目的也是让我们去操作它的两端数据,不去中间搞事。

那么回过头来看选用双端队列用作我们的栈和队列的适配器,其实是比较不错的,只操作两端的数据,效率还是比较高的。

相关文章:

stack与queue的简单封装

前言&#xff1a; stack与queue即栈和队列&#xff0c;先进后出/先进先出的特性我们早已了然于心&#xff0c; 在学习数据结构时&#xff0c;我们利用c语言实现栈与队列&#xff0c;从结构体写起&#xff0c;利用数组或指针表示他们的数据成员&#xff0c;之后再一个个实现他们…...

ChatGPT使用技巧整理

目录 1. 让ChatGPT扮演专家角色2. 告诉ChatGPT你的身份3. 限制ChatGPT的回答长度4. 让ChatGPT一步步思考5. 明确你的要求和目的6. 提供充分的背景信息7. 始终结构化思考你的prompt1. 让ChatGPT扮演专家角色 当你们讨论的是市场营销问题时,你可以要求ChatGPT扮演一个具有20年从…...

机器学习笔记 - 维度诅咒的数学表达

1、点之间的距离 kNN分类器假设相似的点也可能有相同的标签。但是,在高维空间中,从概率分布中得出的点往往不会始终靠近在一起。 我们可以用一个简单的例子来说明这一点。 我们将在单位立方体内均匀地随机绘制点(如图所示),并研究该立方体内测试点的 k 个最近邻将占用多少…...

组合计数训练题解

CF40E 题目链接 点击打开链接 题目解法 首先&#xff0c;如果 n , m n,m n,m 一奇一偶&#xff0c;那么答案为 0 0 0 原因是从行和列的角度分析&#xff0c; − 1 -1 −1 个数的奇偶性不同 可以发现 k < max ⁡ { n , m } k<\max\{n,m\} k<max{n,m} 的性质很微…...

P1095 [NOIP2007 普及组] 守望者的逃离

[NOIP2007 普及组] 守望者的逃离 - 洛谷 首先DP的套路就是先找状态 这题也找不出其他的状态了&#xff0c;只有时间一个 所以用f[i]表示时刻i能走多远 而仔细一想实际上决策只有跑、闪现、停三种决策 然而闪现的耗蓝要和跑步一同计算十分麻烦 于是把它们分开算&#xff1…...

Python函数绘图与高等代数互融实例(八):箱线图|误差棒图|堆积图

Python函数绘图与高等代数互融实例(一):正弦函数与余弦函数 Python函数绘图与高等代数互融实例(二):闪点函数 Python函数绘图与高等代数互融实例(三):设置X|Y轴|网格线 Python函数绘图与高等代数互融实例(四):设置X|Y轴参考线|参考区域 Python函数绘图与高等代数互融实例(五…...

联想y7000 y7000p 2018/2019 不插电源 不插充电器, 直接关机 ,电量一直89%/87%/86%,V0005如何解决?

这种问题&#xff0c;没有外力破坏的话&#xff0c;电池不可能突然出事。这种一般是联想的固件问题&#xff0c;有可能发生在系统更新&#xff0c;或者突然的不正常关机或长时间电池过热&#xff0c;原因我不是很清楚。 既然发生了&#xff0c;根据我收集的解决方法&#xff0c…...

stm32与esp8266通信

esp8266 #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h>// 测试HTTP请求用的URL // #define URL "http://162.14.107.118:8086/PC/modifyFoodPrice/0/6"// 测试HTTP请求用的URL // 设置wifi接入信息(请根据您的WiFi信息进行修改) const char…...

组合数 2.1 2.2

O(nlogn)预处理&#xff0c; O(1)查询 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; typedef long long ll; typedef long double ld;const int N 1000…...

【数组的中心位置】python实现-附ChatGPT解析

1.题目 数组的中心位置 题目 给你一个整数数组 nums,请计算数组的中心位置。 数组中心位置是数组的一个下标,其左侧所有元素相乘的积等于右侧所有元素相乘的积。 数组第一个元素的左侧积为 1,最后一个元素的右侧积为 1。 如果数组有多个中心位置,应该返回最靠近左边的那一个…...

黑马JVM总结(二十三)

&#xff08;1&#xff09;字节码指令-init 方法体内有一些字节&#xff0c;对应着将来要由java虚拟机执行方法内的代码&#xff0c;构造方法里5个字节代码&#xff0c;main方法里有9个字节的代码 java虚拟机呢内部有一个解释器&#xff0c;这个解释器呢可以识别平台无关的字…...

AI人体行为分析:玩手机/打电话/摔倒/攀爬/扭打检测及TSINGSEE场景解决方案

一、AI人体行为分析技术概述及场景 人体姿态分析/行为分析/动作识别AI算法&#xff0c;是一种利用人工智能技术对人体行为进行检测、跟踪和分析的方法。通过计算机视觉、深度学习和模式识别等技术&#xff0c;可以实现对人体姿态、动作和行为的自动化识别与分析。 在场景应用…...

HI_NAS linux 记录

dev/root 100% 占用解决记录 通过下面的命令查看各文件夹 大小 sudo du --max-depth1 -h # 统计当前文件夹下各个文件夹的大小显示为M 最终发现Var/log 占用很大空间 发现下面两个 log 占用空间很大&#xff0c;直接 rm-rf 即可 HI NAS python3 记录 # 安装pip3 sudo apt u…...

计算机图形学中的几何光学

文章目录 前言一、图形学中的光学二、光照模型1、经验型&#xff08;简单&#xff09;2、物理型&#xff08;复杂&#xff09; 前言 在学习Shader光照之前了解一下计算机图形学 一、图形学中的光学 镜面反射的效果例子&#xff1a;物体表面高光 慢反射的效果的例子&#xff1a…...

「UG/NX」BlockUI 选择小平面区域 Select Facet Region

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「UG/NX」BlockUI集合&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「DSA」数据结构与算法「File」数据文件格式 目录 控件说…...

【完全二叉树魔法:顺序结构实现堆的奇象】

本章重点 二叉树的顺序结构堆的概念及结构堆的实现堆的调整算法堆的创建堆排序TOP-K问题 1.二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构…...

Maven官方镜像仓库与阿里云云效Maven

一、Maven官方镜像仓库 download maven-3 右击复制链接地址&#xff0c;使用wget命令直接在linux中下载&#xff1a; wget 链接地址history 二、阿里云云效Maven 详情查看maven 配置指南 打开 maven 的配置文件&#xff08; windows 机器一般在 maven 安装目录的 conf/…...

python系列教程215——列表解析与矩阵

朋友们&#xff0c;如需转载请标明出处&#xff1a;https://blog.csdn.net/jiangjunshow 声明&#xff1a;在人工智能技术教学期间&#xff0c;不少学生向我提一些python相关的问题&#xff0c;所以为了让同学们掌握更多扩展知识更好地理解AI技术&#xff0c;我让助理负责分享…...

fonts什么文件夹可以删除吗?fonts文件夹删除了怎么恢复

在电脑上&#xff0c;fonts文件夹是存放字体文件的目录之一。尽管有时可能考虑删除该文件夹以节省硬盘空间或出于其他原因&#xff0c;但删除该文件夹可能会导致系统字体问题&#xff0c;影响用户的正常使用。因此&#xff0c;在删除之前需要考虑是否可以删除fonts文件夹&#…...

【智慧工地源码】智慧工地助力数字建造、智慧建造、安全建造、绿色建造

智慧工地围绕建设过程管理&#xff0c;建设项目与智能生产、科学管理建设项目信息生态系统集成在一起&#xff0c;该数据在虚拟现实环境中&#xff0c;将物联网收集的工程信息用于数据挖掘和分析&#xff0c;提供过程趋势预测和专家计划&#xff0c;实现工程建设的智能化管理&a…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

统计学(第8版)——统计抽样学习笔记(考试用)

一、统计抽样的核心内容与问题 研究内容 从总体中科学抽取样本的方法利用样本数据推断总体特征&#xff08;均值、比率、总量&#xff09;控制抽样误差与非抽样误差 解决的核心问题 在成本约束下&#xff0c;用少量样本准确推断总体特征量化估计结果的可靠性&#xff08;置…...

【JavaEE】万字详解HTTP协议

HTTP是什么&#xff1f;-----互联网的“快递小哥” 想象我们正在网上购物&#xff1a;打开淘宝APP&#xff0c;搜索“蓝牙耳机”&#xff0c;点击商品图片&#xff0c;然后下单付款。这一系列操作背后&#xff0c;其实有一个看不见的“快递小哥”在帮我们传递信息&#xff0c;…...

从0开始一篇文章学习Nginx

Nginx服务 HTTP介绍 ## HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。 ## HTTP工作在 TCP/IP协议体系中的TCP协议上&#…...