c++ - 第11节 - stack和queue类

news2024/11/20 2:34:27

1.标准库中的stack

1.1.stack

stack类的文档介绍:https://cplusplus.com/reference/stack/stack/?kw=stack

注:

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

5.下图所示是官方库中链表list、栈stack、队列queue的声明和栈stack、队列queue的介绍。严格地说,list是一种容器,而stack和queue是一种容器适配器,从下图可以看出,链表list声明的第二个参数是一个空间配置器,栈stack和队列queue的第二个参数是一个容器

栈stack、队列queue(包括后面的priority_queue)是容器适配器,也就是说他们不是自己原生实现的,他们是依靠包装容器适配出来的

1.2.stack类的常用接口说明

使用stack前的说明:

1.使用stack类需要包含stack的头文件,代码为:#include<stack>

注:这里不是包含stack.h是因为会和c语言的库函数冲突,不能直接包含stack.cpp是因为如果项目里面同时两个人都包含stack.cpp,那么就会造成重定义

2.stack类是在std里面的,因此使用stack类需要using namespace std将std展开(如果不展开每次使用stack类需要std::stack)

注:std和iostream是无关的,只不过帮助进行输入输出的cout、cin、enl等是在std里面定义的。如果不输入输出,不包含iostream也可以使用stack类,但是需要展开std

stack的接口:

函数名称

功能说明

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

注:

1.stack里面没有迭代器,因为栈这种数据结构让你随便去遍历反而是不好的,如果随便遍历就保证不了后进先出的功能了,栈里面数据的遍历代码如下图所示

1.3.stack类练习题

练习题一:

题目描述:

题目链接:155. 最小栈 - 力扣(LeetCode)

思路:

思路1:建立两个栈st和minst,st是正常的栈存储数据,minst存储最小值数据。插入时插入到st栈中,插入的值如果大于minst栈top的值,则minst栈再插入top的值,插入的值如果小于minst栈top的值,则minst栈插入st栈插入的值。st栈pop删除数据的时候,minst也跟着删除数据。

例如:st插入5,目前最小值是5,则minst插入5;st插入8,目前最小值是5,则minst再插入5;st插入7,目前最小值是5,则minst再插入5;st插入2,目前最小值是2,则minst插入2,如下图一所示,st进行删除,那么minst也要进行删除,如下图二所示。像前面的操作如果想要得到栈的最小值,直接取minst的的top即可。

  

上面的思路可以优化一下,见下面思路2。

思路2:建立两个栈st和minst,st是正常的栈存储数据,minst存储最小值数据。插入时插入到st栈中,插入的值如果大于minst栈top的值,不做处理,插入的值如果小于minst栈top的值,则minst栈插入st栈插入的值。st栈pop删除数据的时候,如果st删除的数据大于minst栈top的值,不做处理,如果st删除的数据等于minst栈top的值(不存在st删除的数据大于minst栈top的值的情况),minst也跟着删除数据,如下图所示。

代码:

练习题二:

题目描述:

题目链接:栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)

思路:

入栈序列先入栈,每次入栈以后,栈顶跟出栈序列比较,有两种情况:

情况一:能匹配:出栈序列往后,出战。

情况二:不能匹配:有两种情况:(1)如果入栈序列没有走到尾,说明这个数据可能还没入栈,继续入栈(2)如果入栈序列已经走到尾,说明数据一定在栈中,只是顺序不对,出栈序列非法

例1:输入[1 2 3 4 5]和[4 5 3 2 1]序列

出栈序列指向4,入栈序列入栈1,和出栈序列4不匹配,入栈序列入栈2,和出栈序列4不匹配,入栈序列入栈3,和出栈序列4不匹配,入栈序列入栈4,和出栈序列4匹配,出栈序列指向5,入栈序列3,和出栈序列5不匹配,入栈序列入栈5,和出栈序列5匹配,出栈序列指向3,入栈序列3,和出栈序列3匹配,出栈序列指向2,入栈序列2,和出栈序列2匹配,出栈序列指向1,入栈序列1,和出栈序列1匹配,出栈序列没问题

例2:输入[1 2 3 4 5]和[4 3 5 1 2]序列

出栈序列指向4,入栈序列入栈1,和出栈序列4不匹配,入栈序列入栈2,和出栈序列4不匹配,入栈序列入栈3,和出栈序列4不匹配,入栈序列入栈4,和出栈序列4匹配,出栈序列指向3,入栈序列3,和出栈序列3匹配,出栈序列指向5,入栈序列2,和出栈序列5不匹配,入栈序列入栈5,和出栈序列5匹配,出栈序列指向1,入栈序列2,和出栈序列1不匹配,入栈序列已经走到尾,出栈序列非法

代码:

注:上面 return popi==popV.size 和 return st.empty() 两种结束条件都是可以的

练习题三:

题目描述:

题目链接:150. 逆波兰表达式求值 - 力扣(LeetCode)

思路:(后缀表达式计算的思路)

从前往后依次取数据:

(1)如果是操作数:将操作数入栈

(2)如果是运算符:取连续两个栈顶数据进行运算,运算结果继续入栈

数据走完将栈里的操作数出栈,出栈的值就是结果值

例:计算后缀表达式123*+的结果

首先遇到数据1,1是操作数将1入栈,此时栈里的数据为1,走到数据2,2是操作数将2入栈,此时栈里的数据为12,走到数据3,3是操作数将3入栈,此时栈里的数据为123,走到数据*,*是运算符,取连续两个栈顶数据3和2进行运算,结果为2*3=6(连续出两个先出来的是运算符的右操作数,后出来的是运算符的左操作数),将结果6入栈,此时栈里的数据为16,走到数据+,+是运算符,取连续两个栈顶数据6和1进行运算,结果为6+1=7,将7入栈,数据取完将栈里面操作数出栈就是结果,结果为7

代码:

注:

1.中缀表达式就是操作符在中间,后缀表达式就是操作符在后面(我们平时写的都是中缀表达式)

中缀表达式1+2*3转化为后缀表达式就是123*+,后缀表达式123*+的意思就是2和3相乘,然后1加上2和3相乘的结果。本题是给你后缀表达式,让你计算出结果。

2.本题是后缀表达式计算的问题。还有道题是中缀表达式计算的问题,中缀表达式计算问题的解法是先将中缀表达式转成后缀表达式,将计算后缀表达式的值即可,后缀表达式的计算问题我们已经会了,将中缀表达式转成后缀表达式的思路如下所示

思路:(中缀表达式转成后缀表达式的思路)

从前往后依次取数据:

(1)遇到操作数:将操作数输出或者存储(输出还是存 储是看转成后的表达式输出还是存储)

(2)遇到运算符:跟栈顶运算符进行比较,如果栈为空或者比栈顶运算符优先级高就将其入栈,然后再往下取数据;如果比栈顶运算符优先级低或者优先级一样就出栈顶的操作符,然后继续和此时栈顶运算符比较......

数据走完将栈里的运算符依次出栈

例:将中缀表达式1+2*3/2-5转成后缀表达式

首先遇到数据1,1是操作数进行存储,存储空间此时为1,走到数据+,+是运算符,此时栈为空运算符+入栈,走到数据2,2是操作数进行存储,存储空间此时为12,走到数据*,*是运算符,*运算符比栈顶+运算符优先级高,运算符*入栈,走到数据3,3是操作数进行存储,存储空间此时为123,走到数据/,/是运算符,/运算符和栈顶*运算符优先级相同,此时栈顶运算符*出栈,存储空间此时为123*,/运算符继续和此时栈顶运算符+比较,/运算符优先级高,运算符/入栈,走到数据2,2是操作数进行存储,存储空间此时为123*2,走到数据-,-是运算符,-运算符比栈顶/运算符优先级低,此时栈顶运算符/出栈,存储空间此时为123*2/,-运算符继续和此时栈顶运算符+比较,-运算符和+运算符优先级相同,此时栈顶运算符+出栈,存储空间此时为123*2/+,走到数据5,5是操作数进行存储,存储空间此时为123*2/+5,数据取完将栈里面运算符出栈,存储空间此时为123*2/+5-


2.标准库中的queue

2.1.queue

queue类的文档介绍:https://cplusplus.com/reference/queue/queue/

注:

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

2.2.queue类的常用接口说明

使用queue前的说明:

1.使用queue类需要包含queue的头文件,代码为:#include<queue>

注:这里不是包含queue.h是因为会和c语言的库函数冲突,不能直接包含queue.cpp是因为如果项目里面同时两个人都包含queue.cpp,那么就会造成重定义

2.queue类是在std里面的,因此使用queue类需要using namespace std将std展开(如果不展开每次使用queue类需要std::queue)

注:std和iostream是无关的,只不过帮助进行输入输出的cout、cin、enl等是在std里面定义的。如果不输入输出,不包含iostream也可以使用queue类,但是需要展开std

queue的接口:

函数名称

功能说明

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

注:

1.queue里面没有迭代器,因为队列这种数据结构让你随便去遍历反而是不好的,如果随便遍历就保证不了先进先出的功能了,队列里面数据的遍历代码如下图所示


3.标准库中的priority_queue

3.1.priority_queue

priority_queue类的文档介绍:https://cplusplus.com/reference/queue/priority_queue/

注:

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
   empty():检测容器是否为空
   size():返回容器中有效元素个数
   front():返回容器中第一个元素的引用
   push_back():在容器尾部插入元素
   pop_back():删除容器尾部元素
5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

3.2.priority_queue类的常用接口说明

使用priority_queue前的说明:

1.使用priority_queue类需要包含queue的头文件,代码为:#include<queue>,

注:priority_queue类的定义是在queue头文件里的

2.priority_queue类是在std里面的,因此使用priority_queue类需要using namespace std将std展开(如果不展开每次使用priority_queue类需要std::priority_queue)

注:std和iostream是无关的,只不过帮助进行输入输出的cout、cin、enl等是在std里面定义的。如果不输入输出,不包含iostream也可以使用priority_queue类,但是需要展开std

3.优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。
注意:默认情况下priority_queue是大堆。

priority_queue的接口:

函数名称

功能说明

priority_queue()  priority_queue(first, last)
构造一个空的优先级队列
empty( )
检测优先级队列是否为空,是返回true,否则返回false
top( )
返回优先级队列中最大(最小元素),即堆顶元素
push(x)
在优先级队列中插入元素x
pop()
删除优先级队列中最大(最小)元素,即堆顶元素

注:

1.priority_queue优先级队列官方库里的声明和介绍如下图所示,priority_queue模板第二个参数的默认值vector,也就是说默认使用vector作为其底层存储数据的容器

priority_queue优先级队列第三个参数默认传的是仿函数less,传less其实是一个大堆(正常传greater才应该是大堆,这里是c++的一个失误),也就是说priority_queue优先级队列默认取的是大堆。如果想控制成小堆,优先级队列模板中第三个参数传greater仿函数即可。

2.priority_queue里面没有迭代器,因为堆这种数据结构让你随便去遍历反而是不好的,如果随便遍历就保证不了堆的功能了,优先级队列(堆)里面数据的遍历代码如下图所示

优先级队列默认情况下是一个大堆,如上图所示,如果要使用小堆,应该手动传priority_queue优先级队列模板的第二第三个参数,如下图所示

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

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

相关文章

深度学习项目:男女性别识别【附完整源码】

性别分类对于人机交互应用和计算机辅助生理或心理分析等商业领域的许多应用至关重要&#xff0c;因为它包含有关男女特征差异的广泛信息。 本次案例收集了接近二十万的男女数据集图片。 文章目录性别分类简介使用 Python 进行性别分类的机器学习项目导入相关库和数据模型搭建…

Chapter3 Pytorch与机器学习有关函数(一)

3.1 Tensor中统计学有关的函数 3.1.1 平均值、总和 、累积 1.测试结果1 import torcha torch.rand(2, 2)print(a) print(torch.mean(a,)) print(torch.sum(a)) print(torch.prod(a)) 2.测试结果2&#xff1a;数组对第1维操作 import torcha torch.tensor([[1.0,2.0,3.0],[4.…

【毕业设计】酒店评价情感倾向分析系统 - python 深度学习

文章目录0 前言1 概述2 项目所需模块3 数据3.1 数据说明3.1.1 字段说明3.2 数据处理3.2.1 分词处理3.2.3 停用词处理3.2.4 样本均衡3.2.5 建立多层感知机分类模型3.2.6 训练模型3.2.7 网络检测率以及检测结果4 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里…

回归模型介绍

Datawhale开源学习&#xff0c;机器学习课程&#xff0c;项目地址&#xff1a;https://github.com/datawhalechina/leeml-notes 首先讲机器学习中的&#xff1a;回归&#xff0c;回归Regression可以做哪些东西呢&#xff1f; 股票预测 输入为以往股票走势&#xff0c;预测未来…

HTML标签(下)

一、表格标签 1. 表格的主要作用 表格主要用于显示、展示数据。可以让数据规整、有可读性、有条理。 2. 表格的基本语法 <table><tr><td>单元格内的文字</td>...</tr>... </table><table> </table>是用于定义表格的标签 …

nodejs+vue+elementui零食食品o2o商城系统

目 录 摘 要 1 Abstract 1 1 系统概述 4 1.1 概述 4 1.2课题意义 4 1.3 主要内容 4 2 系统开发环境 5 3 需求分析 7 3.1技术可行性&#xff1a;技术背景 7 3.2经济可行性 7 3.3操作可行性&#xff1a; 8 3.4系统设计规则 8 3.5…

对pure pursuit算法的理解和改进

算法实现 purepursuit的核心其实是一个曲率半径的几何计算。 (x, y)是转换到机器人坐标系上的路径点。L是lookahead distance。r是形成的圆弧半径。D是r和x之间的差值。 根据上面的图形&#xff0c;可以发现有下面的几何关系&#xff1a; 同时通过 y2D2r2y^2 D^2 r^2 y2D2r…

java项目-第134期ssm社团管理系统-java毕业设计

java项目-第134期ssm社团管理系统-毕业设计 【源码请到资源专栏下载】 今天分享的项目是《社团管理系统》 该项目分为前台和后台。主要分成两个角色&#xff1a;普通用户、管理员角色。 普通用户登录前台&#xff0c;看到社团官网发布的一些信息。 比如&#xff1a;首页、新闻…

如何在 .NET MAUI 中加载 json 文件?

引言: 按core传统方式添加 AddJsonFile(“appsettings.json”) 在windows平台和ssr工作正常,但是在 ios 和 android 无法用这种方式,因为资源生成方式不一样. 使用内置资源方式不够灵活而且 ios 平台会提示不能复制 json 文件到目录,于是进行了几天的研究,终于能正确使用了. 资…

1-STM32之GPIO点亮LED

我们在基础部分讲了有关GPIO的方面&#xff0c;从这章开始我们进入模块的讲解&#xff0c;从最开始的LED灯到各种传感器模块进行。专栏预计25个章节。后续可能会不定时的增加。 本专栏芯片为STM32F429 对于工程的移植和新建这里不做讲解&#xff0c;对工程建立不懂得&#xff0…

Vue3 - watch 侦听器(超详细使用教程)

前言 它之所以叫侦听器呢&#xff0c;是因为它可以侦听一个或多个响应式数据源&#xff0c;并在数据源变化时调用所给的回调函数。 大白话说呢&#xff0c;就是你传给 watch 侦听器一个响应式变量&#xff0c;然后当这个变量变化时&#xff0c;自动触发一个你定义的函数&#x…

超实用Word小技巧,常用但很少有人记得住

我们在日常工作中经常使用 Word 进行办公。以下常用Word提示可以为您的工作节省时间和精力&#xff0c;让我们来看看。 技巧一&#xff1a;如何纵向复制文本我们一般水平选择文本&#xff0c;你有没有想过垂直选择文本&#xff1f;先按住【Alt】键&#xff0c;然后拖动鼠标左键…

【Python百日进阶-WEB开发】Day179 - Django案例:11短信验证码

文章目录九、短信验证码9.1 短信验证码逻辑分析9.2 容联云通讯短信平台9.2.1 容联云通讯短信平台介绍9.2.2 容联云通讯短信SDK测试9.2.2.1 美多商城meiduo_mall.apps.verifications.libs中新建yuntongxun包&#xff0c;结构如下&#xff1a;9.2.2.2 ccp_sms.py代码9.2.2.3 CCPR…

一起来庆祝属于GISer的节日GIS DAY!

01 概述 作为一名GISer的你&#xff0c;有没有想过其实我们GISer也有自己的节日&#xff1f;这个节日便是GIS DAY&#xff0c;今年的GIS DAY恰在今天&#xff08;2022年11月16日&#xff09;。究竟什么是GIS DAY&#xff1f;这里为大家介绍一下这个节日。 02 什么是GIS DAY …

vue的移动端项目打包成手机的app软件apk格式

目录 前提准备&#xff1a; 1、vue项目npm run build打包成dist文件夹 2、注册hbuilderx账号&#xff0c;获取appid 步骤 一、创建h5app空模版 二、 将打包完成生成dist文件目录复制到新建的项目里 三、检测打包的index.html是否白屏 四、 配置manifest.js应用入口页面…

作为项目经理必须具备的能力

作为项目管理者&#xff0c;每天都要应对项目中的所有问题&#xff0c;安排任务&#xff0c;还要照顾下属的情绪。管理者应该怎么做。 1、计划制定 项目经理作为项目管理者&#xff0c;需要制定计划&#xff0c;合理化分配任务。 项目经理可以使用甘特图制定项目计划&#xf…

微服务feign接口声明的3种方式使用与分析

前言 feign调用方式是微服务调用最为广泛的使用方式&#xff0c;feign接口声明位置也是比较关键的一环。目前来说&#xff0c;feign的3种接口声明方式各自存在利弊&#xff0c;并不存在最优解决方案&#xff0c;只能根据需求去选择。本文中不作详细项目搭建过程&#xff0c;但…

做3D建模的女生多吗?揭露行业比列

有&#xff0c;但是不多&#xff0c;这是常态✅ 其实就像是IT领域的男女比例一样&#xff0c;但是也不是没有。更何况现在女孩子顶半边天&#xff0c;遇到领导是女生的也不少&#xff0c;未来的情况如何也不能完全的预估。 • ❤️事业是热爱做的事&#xff0c;工作是不得不做…

索引【MySQL】

1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c; 并指定索引的类型&#xff0c;各类索引有各自的数据结构实现。 1.2 作用 数据库中的表、数据、索引之间的关系&#xff0c;类似于书架上的图书、…

简洁直观解释精确率、召回率、F1 值、ROC、AUC

混淆矩阵 当我们在做二分类预测时&#xff0c;把预测情况与实际情况的所有结果两两混合&#xff0c;结果就会出现以下4种情况&#xff0c;就组成了混淆矩阵。 P&#xff08;Positive&#xff09;&#xff1a;代表正样本N&#xff08;Negative&#xff09;&#xff1a;代表负样…