【C++ STL】stackqueue

news2024/9/28 1:47:22

文章目录

  • stack&queue
    • 1. 介绍
      • 1.1 stack
      • 1.2 queue
    • 2. 接口
      • 2.1 stack
      • 2.2 queue
    • 3. OJ
      • 3.1 最小栈
      • 3.2 验证栈序列
      • 3.3 逆波兰表达式求值
      • 3.4 用栈实现队列
      • 3.5 用队列实现栈
    • 4. 模拟实现
      • 4.1 stack
      • 4.2 queue


stack&queue

1. 介绍

1.1 stack

栈(Stack)是一种常见的数据结构,它是一种“后进先出”(Last In First Out,LIFO)的数据结构。栈可以看做是一种特殊的线性表,只能在栈顶进行插入和删除操作。栈顶是允许操作的,而栈底是固定的。

栈的插入被称为压栈、进栈、入栈,删除被称为出栈、弹栈。

后进先出,先进后出, L I F O LIFO LIFO 原则(Last In First Out)。

在这里插入图片描述

1.2 queue

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

入队列就是队尾插入数据,出队列就是队头删除数据。

先进先出,后进后出,即 F I F O FIFO FIFO 原则(First In First Out)。

在这里插入图片描述

 

2. 接口

2.1 stack

STL中的栈和队列不是容器而是容器适配器。

template <class T, class Container = deque<T> > 
class stack;

stack 的底层可以使用任何容器,只要该容器支持emptybackpush_backpop_back这些接口。如果没有为stack指定底层容器,默认使用deque。

接口声明解释
explicit stack (const container& ctnr = container())构造函数
bool empty() const判空
size_type size() const元素个数
value_type& top()栈顶元素
void push (const value_type& val)尾插
void pop()尾删
bool operator== (const stack<T,Ctnr>& lhs, const stack<T,Ctnr>& rhs)关系运算

2.2 queue

template <class T, class Container = deque<T> >
class queue;

queue也是容器适配器。底层容器要求和stack一样。

接口声明解释
explicit queue (const container& ctnr = container())构造函数
bool empty() const判空
size_type size() const元素个数
value_type& front()队头元素
value_type& back()队尾元素
void push (const value_type& val)尾插
void pop()头删
bool operator== (const stack<T,Ctnr>& lhs, const stack<T,Ctnr>& rhs)关系运算

3. OJ

3.1 最小栈

最小栈

class MinStack {
public:
    void push(int val) {
        st.push(val);
        if (minST.empty() || val <= minST.top()) {
            minST.push(val);
        }
    }
    void pop() {
        if (st.top() == minST.top()) {
            minST.pop();
        }
        st.pop();
    }
    int top() {
        return st.top();
    }
    int getMin() {
        return minST.top();
    }
private:
    stack<int> st;
    stack<int> minST;
};

准备两个栈,一个用来正常入栈出栈,一个用来存储最小值。

  1. 当入栈元素大于当前最小值时,只入到普通栈,不入最小栈。
  2. 当入栈元素小于等于当前最小值时,将其入到普通栈,也入到最小栈中。

出栈时,判断栈顶元素是否和最小值相等,相等则把最小栈中的元素也弹出。

在这里插入图片描述

3.2 验证栈序列

验证栈序列 / 剑指 Offer 31. 栈的压入、弹出序列

一个入栈序列对应多种出栈序列,只能拿一个栈用来模拟,如果能匹配出当前的出栈序列,则两者是匹配的。

class Solution {
public:
    bool IsPopOrder(vector<int> pushV, vector<int> popV) {
    	stack<int> st; // 模拟栈
        int popi = 0;  // 出数组指针
        for (auto& e : pushV) {
            st.push(e); // 入栈数组只管向栈中入元素
            while (!st.empty() && st.top() == popV[popi]) { // 出栈数组和模拟栈进行比较
                st.pop();
                ++popi;
            }
        }
        return st.empty(); // 出栈数组遍历结束或栈为空
    }
};

定义一个模拟栈,定义两个指针指向出入数组的起始位置,向后遍历。

入栈数组只管向栈中入元素,只有出栈数组和模拟栈进行比较:当栈顶元素和出栈指针所指元素相等时,将栈顶元素出栈并++出栈指针。

成功示例图示

在这里插入图片描述

不成功示例

在这里插入图片描述

待入栈数组遍历结束后,若出栈数组遍历结束或栈为空,说明匹配成功,若栈中仍有元素或出栈数组未遍历结束,说明匹配不成功。

3.3 逆波兰表达式求值

逆波兰表达式求值

中缀表达式转后缀表达式的目的是,将操作符按照运算顺序从左到右依次排好,方便计算机进行运算。

中缀转后缀

遍历中缀字符串:

  • 遇到操作数,直接输出。
  • 遇到操作符,如果是空栈,直接入栈;如果栈非空,将其与栈顶比较优先级;
  • 优先级比栈顶元素高,则入栈,比栈顶低或相等,栈顶出栈并输出。
  • 遍历结束后,将栈中元素全部输出。

后缀运算

遍历后缀表达式:

  • 遇到操作数,直接入栈。
  • 遇到操作符,连续取两个栈顶元素(先出为右,后出为左)作操作数与其运算,运算结果入栈。
  • 遍历结束后,栈顶即结果。
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
    	stack<int> st;
        for (auto& s : tokens) {
            if (s == "+" || s == "-" || s == "*" || s == "/") {
                string optor(s); //得操作符
                int op2 = st.top(); //先出为右操作数
                st.pop();
                int op1 = st.top(); //后出为左操作数
                st.pop();
                switch(s[0]) {
                case '+':
                    st.push(op1 + op2);//将运算结果入栈
                    break;
                case '-':
                    st.push(op1 - op2);
                    break;                   
                case '*':
                    st.push(op1 * op2);
                    break;
                case '/':
                    st.push(op1 / op2);
                    break;
                }
            }
            else {
                st.push(stoi(s)); // 操作数入栈,待遍历得操作符与之运算
            }
        }
        return st.top();//返回栈顶元素
    }
};

3.4 用栈实现队列

用栈实现队列

使用两个栈,一个用来入,一个用来出。

只要出栈为空,就将入栈中的数据全部导入出栈。只有当出栈为空时,才会导入,以免打乱顺序。保证了出栈和取数据时有元素。

class MyQueue {
public:
    void push(int x) {
        _pushST.push(x);
    }
    
    int pop() {
        int tmp = peek(); //返回队头数据的同时进行了转移判断
        _popST.pop();
        return tmp;
    }
    
 	int peek() {
		if (_popST.empty()) { // 只需要在取数据处判断是否需要转移数据
			while (!_pushST.empty()) {
				_popST.push(_pushST.top());
				_pushST.pop();
			}
		}
		return _popST.top();
	} 
    
    bool empty() {
        return _popST.empty() && _pushST.empty();
    }
private:
    stack<int> _pushST;
    stack<int> _popST;
};

在这里插入图片描述

入栈pushST和出栈popST互不影响,分别完成入队的出队的任务。只要popST为空,就将pushST中元素移入即可。

3.5 用队列实现栈

用队列实现栈

用队列实现栈,需要考虑栈是先进后出的结构,都是顺序容器插入操作一致,删除操作需要将队列中的前n-1个元素移入另一个队列,只留最后一个元素。

class MyStack {
public:
    void push(int x) {
        q1.push(x);
    }
    int pop() {
        int tmp = top();
        q1.pop();
        swap(q1, q2);//pop之后交换,把q2变成q1,相当于栈出了栈顶
        return tmp;
    }
    int top() {
        while(q1.size() > 1) {
            q2.push(q1.front());
            q1.pop();
        }
        int tmp = q1.front();
        return tmp;
    }
    bool empty() {
        return q1.empty() && q2.empty();
    }
private:
    queue<int> q1;
    queue<int> q2;
};

 

4. 模拟实现

4.1 stack

适配器是一种设计模式。数据结构栈可以用数组和链表实现,C++中栈被实现成容器的适配器,通过复用底层容器的接口。

template <class T> class stack {
    void push(const T& x) {
        _v.push_back(x);
    }
    //...
private:
    vector<T> _v;
}

直接将容器 vector 作成员变量,所有接口都调用 vector 的接口即可。

template <class T, class Container = deque<T>>
class stack {
public:
    void push(int x) {
        _con.push_back(x);
    }
    void pop() {
        _con.pop_back();
    }
    bool empty() const {
        return _con.empty();
    }
    bool size() const {
        return _con.size();
    }
    T& top() const { 
        return _con.back();
    }
private:
    Container _con;
};

STL直接将容器类型作为类模板参数传入,支持自定义底层容器,并采用缺省参数的形式,指定默认容器为 deque。

4.2 queue

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

private:
    Container _con;
};

queue也是容器适配器,只要按照queue的特性,将适配容器的接口换一下即可。

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

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

相关文章

IP探针双端源码

源码耗费两年半的制作过程 将源码上传至你的服务器或你的主机 可以对接其他东西或者网站其他语言 使用方法 1.参数使用 http://域名/sc.php?id这是生成端 http://域名/sc1.php?id这是生成端生成的链接可以跳转链接 http://域名/ck.php?id这是查看IP 生成端&#xff0c;生成完…

“微软蓝屏”事件敲响网络安全的警钟

文章目录 前言一、对网络安全的警醒二、我们如何应对&#xff1f;总结 前言 “微软蓝屏”事件是一次由微软合作伙伴CrowdStrike的终端安全产品更新与操作系统内核冲突导致的全球性技术故障。这一事件不仅影响了多个国家的航空、银行、金融、零售、餐饮等多个行业&#xff0c;还…

游泳馆管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;会员管理&#xff0c;场馆类型管理&#xff0c;泳池类型管理&#xff0c;饮食类型管理&#xff0c;场馆信息管理&#xff0c;泳池信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首…

美国非农数据低迷引发货币波动

本周&#xff0c;全球外汇市场经历了剧烈波动&#xff0c;主要货币对在美国7月非农就业报告表现疲软的影响下展现出多样化的市场反应。美元指数跌至五个月低点 美国7月非农就业数据意外低于预期&#xff0c;仅增加11.4万个就业岗位&#xff0c;失业率上升至4.3%&#xff0c;加剧…

UE蓝图(一)——自定义事件、函数与宏

自定义事件、函数与宏是UE蓝图中实现功能的三种方式&#xff0c;本文对这三种方式的特点与使用场景进行总结 文章目录 自定义事件函数宏进阶触发与调用函数的访问权限纯函数(Pure function) 参考资料 自定义事件 事件(Events) 是从游戏性代码中调用的节点&#xff0c;其使得蓝…

微信报名二维码怎么做

在这个快节奏的时代&#xff0c;每一个细微的便捷都能成为连接品牌与消费者的桥梁。今天&#xff0c;就让我们一同探索一种创新而高效的营销利器——微信报名二维码&#xff0c;它是如何以简约而不简单的姿态&#xff0c;重新定义活动报名的体验&#xff0c;成为品牌营销中的璀…

FTP未授权访问漏洞(匿名登陆)

FTP未授权访问漏洞&#xff08;匿名登陆&#xff09; FTP弱口令或匿名登录漏洞&#xff0c;一般指使用FTP的用户启用了匿名登录功能&#xff0c;或系统口令的长度太短、复杂度不够、仅包含数字、或仅包含字母等&#xff0c;容易被黑客攻击&#xff0c;发生恶意文件上传或更严重…

江苏苏州高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

苏州高校大学智能制造实验室数字孪生可视化系统平台建设项目&#xff0c;旨在通过数字孪生技术&#xff0c;实现对智能制造过程的实时监测、数据分析与决策支持。该平台不仅能为实验室的教学和科研提供有力支持&#xff0c;还能为企业的智能制造转型提供技术支撑和解决方案。 …

String的底层构造

1.String类对象的构造&#xff08;后面有每一个接口的实现&#xff09; #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace bit {class string{public:typedef char* iterator;typedef const…

提升写作技能:掌握ai写作免费生成器的高效使用法

最近&#xff0c;#沉浸式感受火把节#话题在网络上爆红&#xff0c;相关的宣传视频和文案铺天盖地。 但仔细观察&#xff0c;你会发现这些文案大多千篇一律&#xff0c;缺乏创意。火把节&#xff0c;这个充满激情与神秘的节日&#xff0c;难道就无法以更独特的方式呈现吗&#…

Linux:Linux权限解析

一、Linux下的用户分类 在Linux下&#xff0c;有两种用户&#xff0c;一种是超级用户&#xff0c;一种是普通用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受权限限制&#xff08;制定规则&#xff0c;但不需要遵守规则&#xff09; 普通用户&#xff1…

Stable-Diffusion1.5

SD1.5权重&#xff1a;https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main SDXL权重&#xff1a;https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main diffusers库中的SD代码pipelines&#xff1a;https://github.com/huggingface/di…

来点八股文(六) 网络Linux调优

性能指标 如何衡量程序的网络性能&#xff1f;你会看哪一层&#xff1f;看哪些指标&#xff1f;用哪些工具&#xff1f; 我们通常用带宽、吞吐量、延时、PPS&#xff08;Packet Per Second&#xff09;等指标衡量网络的性能。 应用层**[wrk、Jmeter]** **每秒处理请求数和延…

ComfyUI插件:ComfyUI-BrushNet节点

前言&#xff1a; 学习ComfyUI是一场持久战&#xff0c;而ComfyUI-BrushNet是最近的局部重绘节点&#xff0c;其包含BrushNet和Powerpaint两个主要节点&#xff0c;其中BrushNet有SD1.5和SDXL两个版本&#xff0c;PowerPaint只有1.5的模型可以使用&#xff0c;学会该插件&…

自动驾驶中的三维坐标系变换:原理、方法与实践

文章目录 1. 摘要2. 背景介绍2. 常用的坐标系定义2.1 全局坐标系&#xff08;Global Coordinate System&#xff09;2.2 车体坐标系&#xff08;Vehicle Coordinate System&#xff09;2.3 相机坐标系&#xff08;Camera Coordinate System&#xff09;2.4 图像坐标系&#xff…

Tech Talk: SSD架构与功能模块详解

在之前的系列文章中&#xff0c;我们介绍了固态硬盘的系列知识&#xff0c;包括闪存的介质、原理&#xff0c;以及作为SSD大脑的控制器设计&#xff0c;本文将详细介绍SSD架构以及功能模块。 SSD架构简介 ◎SSD架构示意图 如上图所示&#xff0c;典型的SSD架构包括主机接口、SS…

vue编译为render函数:模板编译过程

模板编译过程&#xff1a;模板编译为render函数&#xff0c;返回vnode。再执行diff和patch。 使用webpack&#xff0c;vue-loader,会在开发环境下编译模板。 虚拟dom和diff算法 1&#xff0c;将dom抽象为虚拟dom&#xff0c;diff算法对比新旧虚拟dom&#xff0c;只把变化的部…

瓜子二手车在财务中台结账核心系统 TiDBTiFlash 实践

作者&#xff1a; jshan 原文来源&#xff1a; https://tidb.net/blog/69f61649 一、前言 瓜子二手车&#xff0c;作为业界独树一帜的二手车电商平台&#xff0c;正以其创新力量重塑整个二手车行业。我们以用户为中心&#xff0c;致力于提供卓越的交易和服务体验&#xff0…

熊海1.0cmsPHP代码审计

熊海1.0cmsPHP代码审计 环境搭建 下载之后直接使用phpstduy搭建就好了 工具使用 比如使用seay审计系统 sql大多数是存在的&#xff0c;但是没有文件上传&#xff0c;这个就是需要自己去验证 漏洞审计 SQL注入 有点多&#xff0c;随便拿一个举例子 就比如我们的登录页面…

蚓链数字化生态系统:引领企业迈向数字化新时代

在当今竞争激烈的商业世界中&#xff0c;数字化转型已成为企业生存和发展的关键。然而&#xff0c;面对复杂的业务流程、海量的数据以及不断变化的市场需求&#xff0c;许多企业在数字化的道路上举步维艰。这时&#xff0c;蚓链数字化生态系统解决方案宛如一盏明灯&#xff0c;…