C++——stack和queue的介绍和使用

news2024/9/21 0:31:07

文章目录

  • 1. stack的介绍和使用
    • 1.1 stack的介绍
    • 1.2 stack的使用
    • 1.3 几个比较经典的oj题
  • 2. queue的介绍和使用
    • 2.1 queue的介绍
    • 2.2 queue的使用
  • 3. 容器适配器
    • 3.1 什么是适配器
    • 3.2 STL标准库中stack和queue的底层结构
    • 3.3 deque的简单介绍(简单介绍)
      • 3.3.1 deque的原理介绍
      • 3.3.2 deque的缺陷
    • 3.4 为什么选择deque作为stack和queue的底层默认容器
    • 3.5 对于stack和queue的模拟实现

1. stack的介绍和使用

1.1 stack的介绍

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

1.2 stack的使用

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

1.3 几个比较经典的oj题

最小栈
思路:
设置两个栈st和minst,st正常插入数据,minst插入当前所有数据中最小的值
当st插入的数据比最小的值(minst.top())还小的时候,才将这个数插入到minst中。
代码:

class MinStack {
public:
    MinStack() {//把它删掉或者不删都可以,对于自定义类型成员 ,默认构造函数 会自动调用它的构造函数

    }
    
    void push(int val) {
        _st.push(val);

        if(_minst.empty())
        {
            _minst.push(val);
        }
        else if(val<=_minst.top())
        {
            _minst.push(val);
        }
        
    }
    
    void pop() {
        if(!_minst.empty())
        {
            if(_minst.top()==_st.top())
            {
                _minst.pop();
            }

            _st.pop();
        }
        
    }
    
    int top() {
       return _st.top();
    }
    
    int getMin() {
        return _minst.top();
    }

    stack<int> _st;
    stack<int> _minst;
};

栈的压入、弹出序列
思路:
模拟出栈
在这里插入图片描述
1、定义一个栈s,然后将入栈序列先入栈
从1开始入栈,然后紧接着让s的栈顶元素也就是1跟出栈序列的第一个数比较,

  • 若相等就出栈,同时更新出栈序列要比较的值,也就是下一次就和出栈序列的第二个数作比较,以此类推;
  • 若不相等,入栈序列继续入栈。

最后如果s里还有元素,那么就说明入栈序列和出栈序列不匹配。
如果s里没有元素,说明入栈序列和出栈序列匹配。
代码:

class Solution {
  public:
    bool IsPopOrder(vector<int> pushV, vector<int> popV) {
        stack<int> s;
        int count = 0;
        for (auto hv : pushV) {
            s.push(hv);
            while (!s.empty() && s.top() == popV[count]) {

                s.pop();
                count++;

                // if (count == popV.size())
                //     break;
            }

        }
        return s.empty();
    }
};

逆波兰表达式求值
逆波兰表达式,也叫做后缀表达式,一般我们见到的是3+4*5这样的叫做中缀表达式,要考虑运算符优先级。转化为中缀表达式就是3 4 5 * +,计算规则是如果遇到操作符,就取它最近的两个操作数运算即可,这样的好处就是不需要考虑运算符优先级了。
代码思路:创建一个int类型的栈s,然后遍历所给vector。遇到操作数的话,由于此题给的操作数是string类型的,那么就需要用stoi将其转化为int类型,然后插入到栈s中;如果遇到操作符,取栈顶元素one和栈顶的下一个元素two计算,因为two比one要先入栈,所以two是第一个操作数,one是第二个操作数,然后将计算结果再插入到栈s中。直到遍历完整个vector数组,最后s中留下的最后一个元素就是所求答案。
代码:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> s;

        for(auto t:tokens)
        {
            if(t=="+"||t=="-"||t=="*"||t=="/")
            {
                int one=s.top();
                s.pop();
                int two=s.top();
                s.pop();

                if(t=="+")
                {
                    s.push(two+one);
                }
                if(t=="-")
                {
                    s.push(two-one);
                }if(t=="*")
                {
                    s.push(two*one);
                }if(t=="/")
                {
                    s.push(two/one);
                }
            }

            else
            {
                int tmp=stoi(t);
                s.push(tmp);
            }

        }
        
        return s.top();

    }
};

2. queue的介绍和使用

2.1 queue的介绍

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

2.2 queue的使用

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

3. 容器适配器

3.1 什么是适配器

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

3.2 STL标准库中stack和queue的底层结构

虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque。

3.3 deque的简单介绍(简单介绍)

3.3.1 deque的原理介绍

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

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂。

3.3.2 deque的缺陷

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是比vector高的。
与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。
但是deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

3.4 为什么选择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的优点,而完美的避开了其缺陷。

3.5 对于stack和queue的模拟实现

stack和queue的模拟实现代码链接

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

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

相关文章

王道操作系统笔记(四)——— 进程同步与互斥

文章目录一、同步与互斥的概念1.1 同步与互斥的基本概念1.2 临界资源与共享资源1.3 独占设备与共享设备二、实现临界区互斥的基本方法2.1 软件实现方法2.1.1 单标志法2.1.2 双标志先检查法2.1.3 双标志后检查法2.1.4 Peterson 算法2.1.5 软件实现方法总结2.2 硬件实现方法2.2.1…

OpenMMLab 计算机视觉 # day2: 图像分类与基础视觉模型

相关资源: github 第二课 图像分类与基础视觉模型 图像分类 图像分类任务&#xff1a;给定一张图片&#xff0c;识别图像中的物体是什么 X∈RH∗W∗3→{1,2..,K}X\in R^{H*W*3} \rightarrow \{1,2..,K\}X∈RH∗W∗3→{1,2..,K}&#xff1b; 从图片中学习&#xff1a; …

Linux--Version Branch

参考链接1. Linux Version BranchLinux的发行版本大体分可为两类。一类是商业公司维护的发行版本&#xff0c;以Redhat&#xff08;RHEL&#xff09;为代表一类是社区组织维护的发行版本&#xff0c;以Debian为代表。2.Debian branchDebian系列主要包含Debian和Ubuntu等。Debia…

操作系统权限提升(十二)之绕过UAC提权-Windows UAC概述

系列文章 操作系统权限提升(一)之操作系统权限介绍 操作系统权限提升(二)之常见提权的环境介绍 操作系统权限提升(三)之Windows系统内核溢出漏洞提权 操作系统权限提升(四)之系统错误配置-Tusted Service Paths提权 操作系统权限提升(五)之系统错误配置-PATH环境变量提权 操作…

已解决TypeError: eval() arg 1 must be a string, bytes or code object

已解决TypeError: eval() arg 1 must be a string, bytes or code object 文章目录报错问题报错翻译报错原因解决方法联系博主免费帮忙解决报错报错问题 粉丝群里面的一个小伙伴&#xff0c;想用Python爬虫然后解析数据&#xff0c;但是发生了报错&#xff08;当时他心里瞬间…

YOLOv8 Ultralytics:最先进的 YOLO 模型——简介+实战教程

YOLOv8 Ultralytics&#xff1a;最先进的 YOLO 模型 什么是 YOLOv8&#xff1f; YOLOv8 是来自 Ultralytics 的最新的基于 YOLO 的对象检测模型系列&#xff0c;提供最先进的性能。 利用以前的 YOLO 版本&#xff0c; YOLOv8 模型更快、更准确 &#xff0c;同时为训练模型提…

unity Vuforia发布移动端,禁止相机权限,出绿屏,强制退出app,如何去掉PERMISSION ERROR

unity Vuforia发布移动端&#xff0c;禁止相机权限&#xff0c;出绿屏&#xff0c;强制退出app&#xff0c;如何去掉PERMISSION ERROR问题描述更改需求解决方案&#xff1a;总结&#x1f4a2;&#x1f4a2;版权声明问题描述 unityvuforia 发布移动端&#xff0c;运行时需要相机…

墨天轮《2022年中国数据库行业年度分析报告》正式发布,精彩抢先看

自2022年4月份起&#xff0c;墨天轮数据社区持续发布月度 《中国数据库行业分析报告》&#xff0c;目前已发布7期&#xff0c;点击超过10万次&#xff0c;下载近万次。 为总结过往&#xff0c;展望未来&#xff0c;墨天轮数据社区正式发布了《2022年中国数据库年度行业分析报告…

MAC(m1)-VsCode上传项目到GitHub仓库

安装Git集成插件&#xff1a; GitHub Pull requests 在Visual Studio Code中查看和管理GitHub拉取请求和问题 Git Graph Git图形化显示和操作 最新最全 VSCODE 插件推荐&#xff08;2023版&#xff09;_白墨石的博客-CSDN博客_vscode插件 在vscode使用git提交推送代码_水…

精选100个Python实战项目案例,送给缺乏实战经验的你

前言&#xff1a;随着 Python 语言的流行&#xff0c;越来越多的人加入到了 Python 的大家庭中。为什么这么多人学 Python &#xff1f;我要喊出那句话了&#xff1a;“人生苦短&#xff0c;我用 Python&#xff01;”&#xff0c;正是因为语法简单、容易学习&#xff0c;所以 …

Jetson 相机编码

Jetson 相机编码 Jetson相机编码是即将发布的“实践”系列的相关代码。有三个存储库: 1. camera-caps JetsonHacks Github存储库camera-caps 通过v4l2-ctl命令行工具提供了一个图形用户界面。您可能会发现&#xff0c;它可以方便地检查连接到Jetson上的V4L2相机的功能。这适…

复试算法练习Day17——从头到尾打印链表

复试算法练习Day17——从头到尾打印链表 题目描述 输入一个链表的头节点&#xff0c;按链表从尾到头的顺序返回每个节点的值&#xff08;用数组返回&#xff09;。 如输入{1,2,3}的链表如下图: 返回一个数组为[3,2,1] 0 < 链表长度 < 10000 示例1 输入&#xff1a;…

SpringMVC之JSON数据传输参数

目录 一&#xff1a;JSON普通数组 二&#xff1a;JSON对象数据 三&#xff1a;JSON对象数组 前面我们说过&#xff0c;现在比较流行的开发方式为异步调用。前后台以异步方式进行交换&#xff0c;传输的数据使用的是JSON,所以前端如果发送的是JSON数据&#xff0c;后端该如何…

C++11中的多线程的支持

C11中的多线程的支持 千禧年以后&#xff0c;主流的芯片厂商都开始生产多核处理器&#xff0c;所以并行编程越来越重要了。在C98中根本没有自己的一套多线程编程库,它采用的是C99中的POSIX标准的pthread库中的互斥锁,来完成多线程编程。 首先来简单一个概念:原子操作,即多线程…

目标检测框架在目标跟踪中的应用

目标检测框架在目标跟踪中的应用 从SiamRPN将跟踪问题定义为one-shot detection任务之后&#xff0c;出现了大量将检测组件由于跟踪的研究。不过Siamese系列一个很大的问题在于其本质仍然是一个模板匹配问题&#xff0c;网络关注的是寻找与target相似的东西&#xff0c;而忽视…

HCIA之数据发送过程

数据发送过程1、同广播域2、跨广播域&#xff08;需要将数据发送给网关&#xff0c;这通过路由器发包&#xff09;&#xff1a;总结1、同广播域 假设PC1要与PC2通讯&#xff1b; PC1不知道PC2的MAC地址&#xff0c;先发送ARP找到PC2的MAC地址&#xff1b; PC1知道了PC2的MAC地…

使用Python Seaborn绘制热力图(heatmap)的时候怎么改变配色

看到最近有些论文中会对Transformer encoder的attention weights进行可视化&#xff0c;通常会使用heatmap&#xff0c;我参考了一些博客&#xff0c;感觉已经总结得很详细了&#xff0c;例如这篇&#xff1a;python绘制热度图(heatmap)_黄思博呀的博客-CSDN博客_python heatma…

pm2:ecosystem.config.js

一、理解ecosystem.config.js1.1、字面理解&#xff1a;pm2生态系统配置文件。1.2、个人理解&#xff1a;pm2配置文件。类似于vite.config.ts、nuxt.config.ts。1.3、理解pm2&#xff1a;pm2 是一个带有负载均衡功能的Node应用的进程管理器。1.4、pm2的能力&#xff1a;1.4.1、…

【React】React入门(一)--React的创建、Jsx语法与组件以及状态(state)

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; 文章目录React简介react的特性虚拟Dom传统dom更新虚拟Domcreate-react-appJSX语法与组件jsx语法class组件函数组件组件嵌套组件…

基于Springboot搭建java项目(三十六)—— 服务监控工具WGCLOUD

服务监控工具WGCLOUD 一、服务监控 ​ “要想晚上睡的好&#xff0c;服务监控少不了”&#xff0c;服务器监控是应用程序开发中必不可少的一部分&#xff0c;做好服务监控有以下几个优点&#xff1a; 能够及时发现应用程序的漏洞能够定位到程序运行的瓶颈&#xff0c;查看程…