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

C++笔记---stack和queue

1. stack的介绍及重要接口

stack---栈,是一种“先进后出,后进先出”的数据结构。

此处的stack是STL库中定义的一个类模板,用于实例化出存储各种类型数据的栈。

bool empty() const;判断栈是否为空(空true/非空false)
size_t size() const;返回栈中的数据个数
T& top();
const T& top() const;
返回栈顶元素(目前最早进最后出的元素)的引用
void push(const T& val);入栈(到栈顶)
void pop();出栈(删除栈顶元素)
void swap(stack& x);交换两个栈的内容

2. queue的介绍及重要接口

queue---队列,是一种“先进先出,后进后出”的数据结构。

此处的queue是STL库中定义的一个类模板,用于实例化出存储各种类型数据的队列。

bool empty() const;判断队列是否为空(空true/非空false)
size_t size() const;返回队列中的数据个数
T& front();
const T& front() const;
返回队头元素(目前最早进最先出的元素)
T& back();
const T& back() const;
返回队尾元素(目前最后进最后出的元素)
void push(const T& val);入队列(到队尾)
void pop();出队列(删除队头元素)
void swap(queue& x);交换两个队列的内容

3. stack和queue的模拟实现

3.1 适配器模式

在STL标准库中,stack和queue并没有被划分为容器,而是被定义为容器适配器。

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

如果有数据结构的知识基础就能知道,stack和queue的底层就是顺序表,是数据访问受到限制的顺序表。

于是,我们可以对顺序表及其接口进行包装,进而实现stack和queue。

3.2 stack的模拟实现

namespace lbz
{template<class T, class container = deque<T>>class stack{public:stack(const container& ctnr = container()):_con(ctnr){}bool empty() const{return _con.empty();}size_t size() const{return _con.size();}T& top(){return _con.back();}const T& top() const{return _con.back();}void push(const T& val){_con.push_back(val);}void pop(){_con.pop_back();}void swap(stack& st){_con.swap(st._con);}private:container _con;};
}

3.3 queue的模拟实现

namespace lbz
{template<class T, class container = deque<T>>class queue{public:queue(const container& ctnr = container()):_con(ctnr){}bool empty() const{return _con.empty();}size_t size() const{return _con.size();}T& front(){return _con.front();}const T& front() const{return _con.front();}T& back(){return _con.back();}const T& back() const{return _con.back();}void push(const T& val){_con.push_back(val);}void pop(){_con.pop_front();}void swap(queue& st){_con.swap(st._con);}private:container _con;};
}

4. deque的简单介绍

一般来说,stack底层适合用vector,queue底层适合用list,但是在标准库中,二者都用deque作为底层容器的缺省参数。

vector和list由于自身的优缺点过于明显且对立,所以二者在实现时因为效率的原因,各自有一些对方没有的接口,这也使得他们分别与stack和list绑定。

而deque可以说是vector和list的缝合怪,因为二者的接口它都支持,所以可以同时作为stack和queue的底层容器,这也就意味着它是将二者优缺点折中的数据结构。

4.1 deque的结构

deque(双端队列)是一种双开口的"连续"空间的数据结构。

双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

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

 其中,map是一个指针数组,存储各个存储数据的数组的地址。

初始的数组存放在map中部位置,当需要向前扩容时,就在将新申请的数组放到已有数组在map中的前一个位置;当需要向后扩容时就将新申请的数组放到map中已有数组的后一个位置。

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

deque迭代器具体是如何运作的比较复杂,在此不作过多论述,简单了解即可。 

4.2 deque的优缺点

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

与list比较,deque的优势是:其底层是连续空间,空间利用率比较高,不需要存储额外字段。

deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

4.3 为什么选择deque作为stack和queue的底层默认容器

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。

但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。

2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。

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

5. 优先级队列priority_queue

顾名思义,优先级队列就是让队中的数据按照优先级(大小顺序等)排队出队。

priority_queue的底层实际上就是堆,既可以依据大小来建大堆小堆,也可以根据自定义的逻辑来制定优先级。

函数指针在C++中并不推荐,这里我们要用到仿函数来传递我们的建堆逻辑。

5.1 仿函数

STL库中priority_queue的原型如下:

template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;

我们可以看到,模板的类型参数列表中有一个Compare类型,其缺省值为less<typename Container::value_type>。

这里的less是一个特殊的类(对应的有greater类),它没有任何成员变量,但是对"()"进行了重载:

template <class T> struct less : binary_function <T,T,bool> {bool operator() (const T& x, const T& y) const {return x<y;}
};

于是,less类就可以这样来使用:

int main()
{int a = 10, b = 10;less<int> isLess;if(isLess(a, b))cout << "a < b" << endl;return 0;
}

这里,由less<int>类实例化出的对象isLess有了类似函数的用法,效果也与函数相同,这就是所谓的仿函数。

通过这样的仿函数,我们就可以将自定义的逻辑传入到类模板中去。

注意,传入"less",建的是大堆;传入"greater",建的是小堆

5.2 priority_queue的常用接口

由于priority_queue实质上就是堆,所以下表中均以堆代指。

bool empty() const;判断堆是否为空(空true/非空false)
size_t size() const;返回堆中的数据个数
const T& top() const;返回堆队头元素(堆顶元素)
void push(const T& val);入堆
void pop();出堆
void swap(priority_queue& x);交换两个堆的内容

5.3 priority_queue的模拟实现

namespace lbz
{template <class T, class Container = vector<T>, class Compare = less<T>>class priority_queue{public:void push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}const T& top(){return _con[0];}size_t size() const{return _con.size();}bool empty() const{return _con.empty();}private:void AdjustUp(size_t child){size_t parent = (child - 1) / 2;while (child > 0 && _com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}}void AdjustDown(size_t parent){size_t child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _com(_con[child], _con[child + 1]))child++;if (_com(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}Container _con;Compare _com;};
}

相关文章:

C++笔记---stack和queue

1. stack的介绍及重要接口 stack---栈&#xff0c;是一种“先进后出&#xff0c;后进先出”的数据结构。 此处的stack是STL库中定义的一个类模板&#xff0c;用于实例化出存储各种类型数据的栈。 bool empty() const;判断栈是否为空(空true/非空false)size_t size() const;返…...

springboot Rabbit MQ topic 配置文件绑定队列和交换机

Spring Boot 中如何将队列和交换机绑定&#xff08;含实例讲解&#xff09; 在使用 Spring Boot 开发高并发的秒杀系统或者其他场景时&#xff0c;RabbitMQ 是常用的消息队列中间件之一。本文将详细讲解如何在配置类中通过代码将队列与交换机绑定&#xff0c;并指定路由键来实…...

Visual Studio 2019密钥

Visual Studio 2019 Enterprise&#xff08;企业版&#xff09;&#xff1a;BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional&#xff08;专业版&#xff09;&#xff1a;NYWVH-HT4XC-R2WYW-9Y3CM-X4V3Y...

【三元组枚举中点】【树状数组】个人练习-Leetcode-1395. Count Number of Teams

题目链接&#xff1a;https://leetcode.cn/problems/count-number-of-teams/description/ 题目大意&#xff1a;给一个数组rating[]&#xff0c;求符合以下任一条件的三元组i, j, k的个数 rating[i] < rating[j] < rating[k]rating[i] > rating[j] > rating[k] …...

Anaconda 中遇到CondaHTTPError: HTTP 404 NOT FOUND for url的问题及解决办法

最近在跑一个开源项目遇到了以下问题&#xff0c;查了很多资料都大&#xff08;抄&#xff09;同&#xff08;来&#xff09;小&#xff08;抄&#xff09;异&#xff08;去&#xff09;的&#xff0c;解决不了根本问题&#xff0c;费了很大的劲终于得以解决&#xff0c;记录如…...

数据库系统 第51节 数据库事务管理

数据库事务管理是数据库管理系统&#xff08;DBMS&#xff09;中用于确保数据完整性和一致性的一组机制。事务是一组不可分割的操作序列&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败。以下是数据库事务管理的关键组成部分的详细叙述&#xff1a; 1. 事务隔离级别…...

分解+优化+组合+对比!核心无忧!VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测

分解优化组合对比&#xff01;核心无忧&#xff01;VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测 目录 分解优化组合对比&#xff01;核心无忧&#xff01;VMD-SSA-Transformer-LSTM多变量时间序列光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.…...

二十三种设计模式之建造者模式(类比汽车制造厂好理解一些)

目录 1. 设计模式的分类 2. 定义 3. 建造者模式通常包含以下几个角色 4. 示例代码 5. 建造者模式的主要优点 1. 设计模式的分类 创建型模式(五种)&#xff1a;工厂方法模式、单例模式、抽象工厂模式、原型模式、建造者模式。 结构型模式(七种)&#xff1a;适配器模式、代…...

macos 系统文件操作时提示 Read-only file system 解决方法

这个情况是因为文件系统为只读, 需要我们执行一下命令重新将系统文件挂载为读写模式, 命令如下: sudo mount -uw / 这里的 mount 就是硬盘挂载命令, 后面的 -uw选项说明如下, 最后的 / 表示的是跟目录, 可以指定要修改的挂载路径,也可以默认. -u -u标志表示应更改已装载文…...

银行业务架构指导应用架构规划及设计方法

摘要 业务架构指导应用架构设计方法是指依托业务架构设计成果,开展应用架构应用划分设计、IT服务分层设计和数据模型设计的方法。通过业务架构指导应用架构设计,以IT研发项目驱动的方式,由IT系统落地业务架构设计成果,实现对业务流程快速拼接和产品灵活配置的支持,从而提升…...

最全面IO流介绍

1.字符集介绍 标准ASCII字符集&#xff1a;使用1个字节存储一个字符&#xff0c;首尾是0&#xff0c;总可以表示128个字符。是美国信息交换标准代码&#xff0c;包含英文、符号等等。 GBK汉字编码字符集&#xff0c;包含2万多个汉字等字符&#xff0c;GBK中一个中文字符编码成…...

fastadmin 文件上传腾讯云

1-安装腾讯云SDK composer require qcloud/cos-sdk-v5 2-腾讯云配置 <?phpnamespace app\common\controller;use Qcloud\Cos\Client; use think\Controller; use think\Db;class Tencent extends Controller {/*** 上传文件* param $config* param $key* return array*/p…...

《机器学习》—— PCA降维

文章目录 一、PCA降维简单介绍二、python中实现PCA降维函数的介绍三、代码实现四、PCA降维的优缺点 一、PCA降维简单介绍 PCA&#xff08;主成分分析&#xff0c;Principal Component Analysis&#xff09;是一种常用的数据降维技术。它通过线性变换将原始数据转换到新的坐标系…...

植物三萜皂苷生物合成途径及调控机制研究进展-文献精读48

摘要 三萜皂苷(triterpenoids saponins)是由三萜皂苷元和一个或多个糖基和/或其他化学基团缩合而成的一系列结构多样的天然化合物[1], 主要分布在五加科、蝶形花科、石竹科、桔梗科、毛茛科、玄参科、葫芦科等植物中[2]. 植物中三萜皂苷常分布在特定的器官和组织, 如人参(Pana…...

server 2016搭建FTP服务

目录 一、实验环境 二、在server 2016上面安装FTP服务 三、在server 2016上面配置FTP服务 四、创建用户&#xff08;也可创建用户组&#xff0c;给用户组赋予权限&#xff09; 一、实验环境 windows server 2016用于安装ftp服务 windows 10作为客户端进行测试。 二、在s…...

物理学基础精解【4】

文章目录 运动和力质点运动机械运动的参考系运动的相对性运动学中坐标系 参考文献 运动和力 质点运动 一个物体相对于另一个物体的位置或一个物体的某些部分相对于其他部分的位置 &#xff0c;随着时间而变化的过程&#xff0c;叫机械运动 。质点是一个物理学中的理想化模型&…...

【区块链 + 人才服务】Blockchain Workshop- 区块链编程实践平台 | FISCO BCOS应用案例

Blockchain Workshop v2.0&#xff08;以下简称 BCW v2.0&#xff09;是点宽网络科技有限公司升级的全新区块链实践教育平台产品。 BCW v2.0 区块链实践教育平台面向高校区块链专业人才培养&#xff0c;用于区块链专业技术学习和智能合约编程学习&#xff0c;平台基于 FISCO BC…...

Java面试篇基础部分-Java中常用的I/O模型

阻塞I/O模型 阻塞式的I/O模型是一种非常常见的I/O模型机制,在进行数据读写操作的时候,客户端会发生阻塞等待。 工作流程如图所示,该用户线程一直阻塞,等待内存中的数据就绪;内存中的数据就绪之后,内核态的数据将拷贝到用户线程中,并且返回I/O的执行结果到用户线程。这个…...

如何使用python运行Flask开发框架并实现无公网IP远程访问

文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask&#xff0c;以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架&#xff0c;采用Python编程语…...

第三届828 B2B企业节开幕,大腾智能携手华为云共谱数字化新篇章

8月27日&#xff0c;由华为携手上万家伙伴共同发起的第三届828 B2B企业节在贵州正式开幕。 本届企业节推出上万款数智产品&#xff0c;600多个精选解决方案&#xff0c;旨在融通数智供需&#xff0c;加速企业智改数转&#xff0c;助推中国数智产业实力再升级。中共贵州省委副书…...

Linux网络编程IO管理

网络 IO 涉及到两个系统对象&#xff0c;一个是用户空间调用 IO 的进程或者线程&#xff0c;一个是内核空间的内核系统&#xff0c;比如发生 IO 操作 read 时&#xff0c;它会经历两个阶段&#xff1a; 等待内核协议栈的数据准备就绪&#xff1b;将内核中的数据拷贝到用户态的…...

SpringCloud集成ELK

1、添加依赖 <dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>6.1</version> </dependency>2、在logback-spring.xml中添加配置信息&#xff08;logback-sp…...

【卷起来】VUE3.0教程-06-组件详解

各位看官&#xff0c;点波关注和赞吧 组件允许我们将 UI 划分为独立的、可重用的部分&#xff0c;并且可以对每个部分进行单独的思考。在实际应用中&#xff0c;组件常常被组织成层层嵌套的树状结构&#xff1a; 这和我们嵌套 HTML 元素的方式类似&#xff0c;Vue 实现了自己的…...

JS Web

Web API 元素通用属性 元素自身属性 事件处理...

【Linux】传输层协议——UDP

零、传输层的作用是负责数据能够从发送端传输到接收端 一、再来认识一下端口号 端口号&#xff08;Port&#xff09;标识了一个主机进行通信的不同的应用程序。在TCP/IP协议中&#xff0c;用“源IP”&#xff0c;“源端口号”&#xff0c;“目的IP”&#xff0c;“目的端口号”…...

算法学习攻略总结 : 入门至进阶,通关之路指南

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; <搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到…...

《卷积神经网络 CNN 原理探秘》

CNN基本原理详解 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;简称CNN&#xff09;&#xff0c;是一种前馈神经网络&#xff0c;人工神经元可以响应周围单元&#xff0c;可以进行大型图像处理。卷积神经网络包括卷积层和池化层。 卷积神经网络是受…...

C#获取计算机信息

目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Management; n…...

派遣函数 - 通过设备链接打开设备

利用文件IO相关的Wn32API对设备进行“打开”和“关闭”操作。要打开设备&#xff0c;必须通过设备的名字才能得到该设备的柄。前面介绍过&#xff0c;每个设备都有设备名称&#xff0c;如HelloDDK驱动程序的设备名为“Device\\MyDDKDevice”&#xff0c;但是设备名无法被用户模…...

Vue 2 中的 `$set` 方法详解

在 Vue 2 中&#xff0c;响应式数据的更新非常重要&#xff0c;因为它确保了当数据改变时&#xff0c;视图能够自动更新。Vue 使用一套高效的机制来追踪依赖并在数据变化时更新视图。然而&#xff0c;在某些情况下&#xff0c;直接修改对象的属性可能不会触发视图更新。这时&am…...