【C++】---Stack和Queue的用法及其模拟实现

news2024/9/22 5:15:00

文章目录

  • Stack
    • 最小栈
    • 栈的弹出压入序列
    • 逆波兰表达式求值
    • 用栈实现队列
    • 模拟实现
  • queue
    • 用队列实现栈
    • 模拟实现

Stack

stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。它的使用和之前学习的vector等容器类似,都具有插入、删除、判空功能,具体的实现就做几道OJ题来感受一下,也可以查看文档进行了解。

最小栈

image-20230213193037356

因为栈的性质是后进先出,所以可以利用这个性质。首先创建两个栈,一个用于压栈(s1),一个用于记录较小元素的栈(s2)。首先每一次压栈s1都会将元素保存,如果s2栈顶的元素比最近压栈的元素大或者当s2为空时,则s2将元素入栈。这样操作就能保持每一次s2里面最近一次进栈的元素都是以压栈元素中最小的元素,此时我们只需要每次取出s2栈顶的元素就是最小元素。如果s1进行出栈操作,那么如果s2的栈顶元素等于s1出栈的元素,那么s2也要进行出栈,这样才能保持住s2的栈顶元素是最小的。

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) {
        s1.push(val);
        if(s2.empty() || s2.top() >= val)
            s2.push(val);
    }
    
    void pop() {
        if(s1.top() == s2.top())
            s2.pop();
        s1.pop();
    }
    
    int top() {
        return s1.top();
    }
    
    int getMin() {
        return s2.top();
    }

private:
    stack<int> s1;
    stack<int> s2;

};

栈的弹出压入序列

image-20230213194455821

这道题考验的就是我们对于后进先出性质的应用,首先一定得判断一下两个序列的长度是否一样,如果不一样那就肯定不对了。接着我们可以对入栈序列进行依次入栈,每一次入栈的元素都和出栈序列的元素比较,如果相等那么出栈序列的比较元素就往后一个,刚入栈的元素就出栈。这样依次反复循环如果栈里的元素全部出栈完并且此时出栈序列所有元素都比较完即为匹配成功。反之其他情况匹配失败

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        if(pushV.size() != popV.size())
            return false;

        //创建栈和记录两个序列的比较个数
        int out = 0;
        int in = 0;
        stack<int> s;

        //如果出栈序列比较完即推出训话
        while(out < popV.size()){

            //如果栈为空或者栈顶元素不等于出栈序列的比较元素则继续入栈
            while(s.empty() || s.top() != popV[out]){

                if(in < pushV.size())
                    s.push(pushV[in++]);
                
                //如果全部元素都入栈但出栈序列没有比较完则匹配失败
                else
                    return false;
            }

            //如果栈顶元素等于出栈序列比较元素则出栈
            s.pop();
            ++out;
        }

        return true;
    }
};

逆波兰表达式求值

image-20230213200705721

逆波兰表达式简单理解就是将运算符放到运算数的后面,因此这道题可以使用栈来完成。首先如果遇到数字就入栈,遇到运算符就不用入栈了,用两个变量来接受栈的两个元素进行运算之后再把结果入栈,这样每一次的运算结果都是栈顶元素,依次循环直至结束。此时栈顶的元素就是最后的运算结果。

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for (auto e : tokens) {
            if (e == "+" || e == "*" || e == "-" || e == "/") {
                int right = st.top();
                st.pop();
                int left = st.top();
                st.pop();
                switch (e[0]) {
                    case '+':
                        st.push(left + right);
                        break;
                    case '-':
                        st.push(left - right);
                        break;
                    case '*':
                        st.push(left * right);
                        break;
                    case '/':
                        st.push(left / right);
                        break;
                }
            }
            else
                //需要将字符串转为整型才可以入栈
                st.push(stoi(e));
        }
        return st.top();
    }
};

用栈实现队列

image-20230213203053798

这道题如果用C语言写就十分的不方便,什么都得自己造。但是用C++有了STL之后就十分的轻松。思路很简单,用两个栈实现队列的先进先出性质。

class MyQueue {
public:
    MyQueue() {

    }
    
    void push(int x) {
        ins.push(x);
    }
    
    int pop() {
        if(outs.empty()){
            while (!ins.empty()) {
                outs.push(ins.top());
                ins.pop();
            }
        }

        int x = outs.top();
        outs.pop();
        return x;

    }
    
    int peek() {
        if(outs.empty()){
            while (!ins.empty()) {
                outs.push(ins.top());
                ins.pop();
            }
        }

        int x = outs.top();
        return x; 
    }
    
    bool empty() {
        return ins.empty() && outs.empty();
    }

private:
    stack<int> outs;
    stack<int> ins;
};

模拟实现

stack其实是一种适配器设计模式,它的接口实现和vector非常的相像,因此我们可以直接使用vector去实现stack

#pragma once

#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<stack>
using namespace std;

namespace my {
	template<class T, class con = vector<T>>
	class stack {
	public:
		void push(const T& x) {
			_con.push_back(x);
		}

		void pop() {
			_con.pop_back();
		}

		const T& top() {
			return _con.back();
		}

		bool empty() {
			return _con.empty();
		}

	private:
		con _con;
	};
}

queue

队列和栈其实都是一样的接口和功能,不同的是队列是一种先进先出的容器,和栈刚好相反。还有就是栈的底层是数组而队列的底层是链表,因此queue多了返回队头和队尾的接口。

用队列实现栈

image-20230213205546685

这个和上面的用栈实现队列是一样的,都是为了模拟出各自的性质,所以这里也可以用两个队列去实现。

class MyStack {
public:
    MyStack() {

    }
    
    void push(int x) {
        //元素先入第二个队列,保证最先入队列的元素在队头
        q2.push(x);
        //将原队列的所有元素依次入第二个队列,保证队列结构
        //再进行交换
        while(!q1.empty()){
            q2.push(q1.front());
            q1.pop();
        }
        swap(q1, q2);
    }
    
    int pop() {
        int x = q1.front();
        q1.pop();
        return x;
    }
    
    int top() {
        return q1.front();
    }
    
    bool empty() {
        return q1.empty();
    }

private:
    queue<int> q1;
    queue<int> q2;

};

模拟实现

queue也是一种适配器设计模式,所以也可以用已有的容器去实现它,因为queue的底层实现是链表,所以我们用list去实现

#pragma once

#include"stack.h"

namespace my2 {
	template<class T, class con = list<T>>
	class queue {
	public:
		void push(const T& x) {
			_con.push_back(x);
		}

		void pop() {
			_con.pop_front();
		}

		const T& top() {
			return _con.front();
		}

		bool empty() {
			return _con.empty();
		}

	private:
		con _con;
	};
}

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

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

相关文章

KDZD880 智能蓄电池放电测试仪

一、产品概述 智能蓄电池放电测试仪主要用于电信、移动、联通、电力直流行业的后备电源铅酸蓄电池的放电测试&#xff0c;具备蓄电池快速容量测试、在线监测及容量核对测试三大功能于一体的产品&#xff0c;集成化程度高、体积小巧、功能完善。 该设备是针对整组 12V-600V 蓄…

JavaScript高级程序设计读书分享之3章——3.4数据类型

JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 ECMAScript 有 6 种简单数据类型&#xff08;也称为原始类型&#xff09;&#xff1a;Undefined、Null、Boolean、Number、String 和 Symbol&#xff08;es6新增&#xff09;。 还有一种复杂数据类型叫…

vim编辑器和gcc/g++编译器和gdb调试器和make/makefile自动化构建工具的使用

vim的三种模式(其实有好多模式 )&#xff08;1&#xff09;.命令模式&#xff08;2&#xff09;.插入模式&#xff08;3&#xff09;.底行模式vim的基本操作vim的命令模式的基本操作vim的插入模式的基本操作vim的底行模式的基本操作vim的配置gcc和g相关操作&#xff08;1&#…

XCP实战系列介绍11-几个常用的XCP命令解析

本文框架 1.概述2. 常用命令解析2.1 CONNECT连接(0xFF)2.2 SHORT_UPLOAD 命令(0xF4)2.2 SET_MTA (0xF6)2.3 MOVE命令(0x19)2.4 GET_CAL_PAGE(0xEA)2.5 SET_CAL_PAGE(0xEB)2.6 DOWNLOAD(0xF0)1.概述 在文章《看了就会的XCP协议介绍》中详细介绍了XCP的协议,在《XCP实战系列介绍…

Python面试——装饰器

知识链接&#xff1a; 装饰器 装饰器可调用的对象&#xff0c;其参数是被装饰的函数。装饰器可能会处理被装饰的函数然后把它返回&#xff0c;或者将其替换成另外一个函数或者可调用对象。 装饰器有两大特性&#xff1a; 能把被装饰的函数替换成其他函数&#xff08;在元编程…

面试腾讯测试岗后感想,真的很后悔这5年一直都干的是基础测试....

前两天&#xff0c;我的一个朋友去大厂面试&#xff0c;跟我聊天时说&#xff1a;输的很彻底… 我问她&#xff1a;什么情况&#xff1f;她说&#xff1a;很后悔这5年来一直都干的是功能测试… 相信许多测试人也跟我朋友一样&#xff0c;从事了软件测试很多年&#xff0c;却依…

树莓派用默认账号和密码登录不上怎么办;修改树莓派的密码

目录 一、重置树莓派的默认账号和密码 二、修改树莓派的密码 三、超级用户和普通用户的切换 一、重置树莓派的默认账号和密码 在SD卡中根目录建立文件userconf 在userconf中输入如下内容&#xff1a; pi:$6$/4.VdYgDm7RJ0qM1$FwXCeQgDKkqrOU3RIRuDSKpauAbBvP11msq9X58c8Q…

STM32开发(10)----CubeMX配置基本定时器

CubeMX配置基本定时器前言一、定时器的介绍二、实验过程1.实验材料2.STM32CubeMX配置基本定时器2.代码实现3.编译烧录4.硬件连接5.实验结果总结前言 本章介绍使用STM32CubeMX对基本定时器进行配置的方法&#xff0c;STM32F103高性能系列设备包括基本定时器、高级控制定时器、通…

JavaEE-HTTP协议(一)

目录什么是HTTP协议&#xff1f;协议格式如何看到HTTP的报文格式&#xff1f;HTTP请求HTTP响应URLURL encode/decode什么是HTTP协议&#xff1f; 计算机网络&#xff0c;核心概念&#xff0c;网络协议 网络协议种类非常多&#xff0c;其中一些耳熟能详的&#xff0c;IP,TCP,UD…

shell命令行并行神器 - parallel

shell命令行并行神奇 - parallel 概述 GNU parallel 是一个 shell 工具&#xff0c;用于使用一台或多台计算机并行执行作业。作业可以是单个命令或必须为输入中的每一行运行的小脚本。典型的输入是文件列表、主机列表、用户列表、URL 列表或表列表。作业也可以是从管道读取的…

98年的确实卷,公司新来的卷王,我们这帮老油条真干不过.....

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

电脑麦克风没声音怎么办?这3招就可以解决!

最近有用户在使用电脑麦克风进行视频录制时&#xff0c;发现麦克风没有声音。这是什么原因&#xff1f;电脑麦克风没有声音怎么办&#xff1f;关于解决方案&#xff0c;我专门整理了三种方法来帮你们&#xff0c;一起来看看吧&#xff01; 操作环境&#xff1a; 演示机型&#…

在TitanIDE中使用ChatGPT辅助科研开发

作者&#xff1a;行云创新CEO 马洪喜 命题&#xff1a;太空望远镜拍摄的照片处理 假设&#xff1a;我是图形科学家&#xff0c;但不是特别懂Python 先上传一张银河系照片&#xff0c;目的是把彩色转成灰度&#xff1a; 然后我不会啊&#xff0c; 问问chatGPT 彩色图片转灰度…

电话号码的字母组合-力扣17-java

一、题目描述给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。示例 1&#xff1a;输入&#xff1a;digits "23"输出…

Android 一体机研发之修改系统设置————自动锁屏

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解自动锁屏。 自动锁屏功能&#xff0c;这个可以根据…

简述springIOC容器的bean加载流程

参考笔记:https://blog.51cto.com/u_14006572/3118363 https://zhuanlan.zhihu.com/p/386335813 https://blog.csdn.net/mrathena/article/details/115654379 目录结构 spring ioc容器的加载&#xff0c;大体上经过以下几个过程&#xff1a; 资源文件定位、解析、注册、实例化…

UWA Pipeline 2.4.1 版本更新说明

UWA Pipeline是一款面向游戏开发团队的本地协作平台&#xff0c;旨在为游戏开发团队搭建专属的DevOps研发交付流水线&#xff0c;提供可视化的CICD操作界面、高可用的自动化测试以及UWA性能保障服务的无缝贴合等实用功能。 在本次UWA Pipeline 2.4.1版本更新中&#xff0c;主要…

PIL.Image与cv2之间的常用API汇总

简单介绍 主要是因为经常用到这两个&#xff0c;经常弄混淆&#xff0c;所以&#xff0c;总结一番。持续更新。 from PIL import Image import cv2 as cv import numpy as np import matplotlib.pyplot as plt1、读取文件与写入文件 1.1 Image.open() img_pil Image.open…

电商数据监测——中国白酒行业数据浅析

大国盛世酿,万家潭酒香。中国白酒是中国特色文化之一。 2022年&#xff0c;国内白酒总产量为671.2万千升&#xff0c;处于持续下滑的态势。 白酒产量不佳&#xff0c;但线上平台的销售情况却成绩优异。2022年&#xff0c;京东平台白酒的年度总销量超3500万件&#xff0c;同比去…

操作系统开发:编写开机引导

操作系统是用来管理与协调硬件工作的&#xff0c;开发一款操作系统有利于理解底层的运转逻辑&#xff0c;本篇内容主要用来理解操作系统是如何启动的&#xff0c;又是如何加载磁盘中的内核的&#xff0c;该系列文章参考各类底层书籍&#xff0c;通过自己的理解并加以叙述&#…