C++STL初阶(11):stack和queue的使用

news2024/11/15 5:52:57

栈和队列的先导知识在这里:C语言基础数据结构——栈和队列_栈和队列 插入取出数据-CSDN博客

1.容器适配器

从栈和队列开始,不少教材就不叫他们容器了,而是叫容器适配器

栈不是一种完全不同的数据结构,而是基于顺序表或者链表而实现的。

“stacks are a type of container adaptor”

栈和队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,stack和 queue都 提供了一组特定的成员函数来访问其元素。

 

Last In First Out:最后一个入栈的第一个出去


 2. stack的工作原理以及使用

                            

                                

练手:最小栈

155. 最小栈 - 力扣(LeetCode)

思路一,利用双栈,第一个栈正常出入数据,第二个栈记录当前数据下的最小数据。

比如左栈先进12,此时最小的就是12,那么右栈就进12;同理4;当左栈进56时,右栈依然是栈顶存有最小数据4,所以再进一个4即可。

            

改进:以上方法虽然没错,但是会重复进很多个相同的元素,是否可以只进一次相同的元素呢?

我们给存放小数的那个栈叫“小栈”

只有当新入的元素比当前小栈的栈顶更小的时候我们才会继续入栈。

先不看两边栈顶的1,左栈是12 4 56 1 35  小栈就应该是12  4  1。

此时出栈的逻辑就会复杂一点,当左栈的元素大于小栈时,只出左栈即可,右栈不动就行。

当左栈即将出栈的元素大小和小栈的栈顶元素大小一样的时候,左栈和小栈同时出栈。

接着再来看红箭头指的1和左栈最上面的1:换句话说,当入栈的元素和最小值是一样的时候,是否在小栈里面也应该再入一个1呢?

答案是需要的:每当进入一个 小于等于当前小栈的栈顶元素时,都需要在小栈上加上压入的元素


再看个例子

                          

删了需要更新。

使用双栈解决

                   

只有当更小的值进入时才把更小的放入minst里去

                     

出现与当前最小值相等的也需要进

                  

函数名的push和_st.push()中的push不是同一个,后面是库中的push,第一个是我们自己实现的push

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(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;
};

压栈入栈序列问题 

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

我们依然借助新建立一个栈来实现这个功能:

将push中的数据一个一个压入,每当压入的数据和出栈数据一样时就进行比较。

                           

 bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        stack<int> st;
        size_t i = 0,j = 0 ;
        for( ; i < pushV.size() ; ++i){
            st.push(pushV[i]);
            while(j<popV.size() && st.top() == popV[j]){
                j++;
                st.pop();
                if (st.empty()) break;
            }
        }
        while(j<popV.size() && st.top() == popV[j]){
                j++;
                st.pop();
        }
        if(st.empty()) return true;
        return false;
    }

在使用中我们发现,stack的top不会检查是否为空,也不会在栈为空时有特殊的返回值:一旦对空栈进行top,会直接出现运行错误。

 


3.队列

       队列是一种容器适配器,专门用于在 FIFO 上下文 ( 先进先出 ) 中操作,其中从容器一端插入元素,另一端提取元素。
底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操
:
empty :检测队列是否为空
size :返回队列中有效元素的个数
front :返回队头元素的引用
back :返回队尾元素的引用
push_back :在队列尾部入队列
pop_front :在队列头部出队列
不同于 栈的是:队列的底层多是使用deque

 

使用队列来回忆队列:

102. 二叉树的层序遍历 - 力扣(LeetCode)

          

复习一下C语言部分我们对二叉树的学习内容:

抛开此题的具体要求,二叉树的层序遍历是相对简单的事情:

一层带下一层即可。先入3,要出3的时候入3的左节点(若左节点存在),再入右节点(若右节点存在)。再当9要出的时候,入9的左右节点,但此处9是叶子,就不再入了。然后出20,再入20的左右节点。

如下图: 

         

问题在于,此题要返回二维数组(vector的vector),那么如何在非满二叉树情况下一层一层的输入到vector就成了问题。

思路一:

使用两个队列。

另外一个队列来记录当前的数据属于第几排


思路二 

使用一个变量levelSize而非队列来控制一层一层出:(本质和思路一差不多,思路一相当于是给每一个数据做记号,记录该结点是哪一层的,思路二则是使用一个数据整体记录。)

如何计数一层有多少个数呢?

每一层都会在上一层全部出完时完全进入队列,此时队列的size()就表示该层的数据个数

 vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> vv;
        if (root==nullptr) return vv;

        queue<TreeNode*> q;
        q.push(root);
        int LevelSize = 1; //根节点一定只有一个

        while(!q.empty()){
        vector<int> v;

        while(LevelSize--){
            TreeNode* front = q.front();
            q.pop();

            if(front->left) q.push(front->left);
            if(front->right) q.push(front->right);

            v.push_back(front->val);
        }

        vv.push_back(v);
        LevelSize = q.size();
        }
        return vv;
    }

 

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

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

相关文章

家里总有宠物浮毛怎么办?除了宠物空气净化器真没更轻松的招了!

从几年前口罩问题爆发开始&#xff0c;我就养成了自我防护的习惯&#xff0c;家里常备口罩、消毒水&#xff0c;每天也会定时开窗通风。但是&#xff0c;由于现在天气热了&#xff0c;大多时候都闷在家里开着空调。家里两只猫时不时打个架&#xff0c;满屋子那猫毛飞得啊&#…

算法日记day 39(动归之打家劫舍)

一、打家劫舍1 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。…

Containerd 介绍

早之前的 Docker Engine 中就有了 containerd&#xff0c;只不过现在是将 containerd 从 Docker Engine 里分离出来&#xff0c;作为一个独立的开源项目&#xff0c;目标是提供一个更加开放、稳定的容器运行基础设施。分离出来的 containerd 将具有更多的功能&#xff0c;涵盖整…

centos7安装Oracle 11g数据库

目录 一、安装前准备1、安装前置工具&#xff08;安装过可以忽略&#xff09;2、更配yum源2.1、备份原有源&#xff1b;2.2、下载阿里云base源和epel源&#xff1b;2.3、清理yum缓存2.4、生成新的缓存2.5、更新系统中所有软件到最新版&#xff08;按需谨慎操作&#xff09; 3 修…

做代理海外仓赚钱?代理仓如何实现盈利?

随着跨境电商与物流的火热&#xff0c;海外仓作为跨境贸易的新基建&#xff0c;也成为了一门生意。具体来说海外仓商业模式是一种通过在跨境贸易中设置离岸仓库&#xff0c;为客户提供包括商品存储、包装、发货、退货和售后服务等一系列跨境电商服务的商业模式。 海外仓的成本主…

跟《经济学人》学英文:2024年08月10日这期 A history-lover’s guide to the market panic over AI

A history-lover’s guide to the market panic over AI Past technologies offer clues to what comes next 原文&#xff1a; Andrew Odlyzko, a professor of mathematics at the University of Minnesota, has a side hustle: he has become one of the world’s foremo…

19523 最长上升子序列长度

### 分析 1. **问题描述**&#xff1a; - 给定一个序列&#xff0c;要求找到最长上升子序列的长度。 - 子序列可以是不连续的&#xff0c;但必须保持顺序。 2. **解决方案**&#xff1a; - 使用动态规划&#xff08;Dynamic Programming, DP&#xff09;来解决这个问…

RCE---无字母数字webshell

<?php if(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code)){die("NO.");}eval($code); }else{highlight_file(__FILE__); } 分析代码&#xff1a;传参不大于35&…

让可视化大屏摆脱面子工程的12个方法

提到可视化大屏&#xff0c;很多老铁就认为这是面子工程&#xff0c;花里胡哨&#xff0c;没啥用处&#xff0c;这固然和认知有关系&#xff0c;那么有没有办法让可视化大屏摆脱这种认知吗&#xff0c;千汇数据工场介绍往日经验&#xff0c;与大家探讨下。 可视化大屏面子工程…

C语言典型例题37

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题3.5 按照按照考试成绩的等级输出百分制分数段&#xff0c;A等为85分以上&#xff0c;B等为70~84分&#xff0c;C等为 60~69分&#xff0c;D等在60分以下&#xff0c;成绩的等级从键盘输入 代码&#xff1a; //…

2024最新上门按摩系统源码APP打包教程!

**xhadmin、免费、开源、可商用** 上门按摩这两年很火&#xff0c;某宝、某鱼上盗版系统盛行&#xff0c;大都是留有后门的系统&#xff0c;加密授权&#xff0c;根本二开不了。 近期很多人反馈我们的上门按摩系统APP打包困难&#xff0c;今天我手把手教大家如何打包上门按摩A…

【CanMVK230】CanMV K230 开箱

【CanMVK230】CanMV K230 开箱 CanMV 是什么CanMV K230开发板硬件资源能做什么 开箱&#xff01;配套资料其他学习资料 K230我买到啦~。话不多说&#xff0c;开始分享我的使用过程。欢迎大神指点。 CanMV 是什么 CanMV开源项目由嘉楠科技&#xff08;Canaan&#xff09;官方创建…

【关于CVE-2024-38077 Windows Server 2012和Windows Server 2018安装安全补丁指南】

文章目录 背景问题描述产生原因解决方案解决步骤1. 安装BypassESU工具2. 补丁安装方法一&#xff1a;使用 Windows 更新功能方法二&#xff1a;手动下载补丁并安装 补丁验证方法一&#xff1a;在“控制面板”-“程序”-”程序和功能”-“已安装更新”中检查是否存在 KBS040434 …

<Linux>进程概念-下

文章目录 目录 前言 一、环境变量 1. PATH 2. HOME 3. 其他环境变量 系统调用接口--getenv 4. 命令行参数 4.1 双参数main 4.2 三参数main 5. 设置环境变量 5.1 本地环境变量 5.1.1 内建命令 5.2 固定环境变量 6. 取消环境变量 7. 小总结 二、程序地址空间 1. 空间划分 2. 进…

haproxy负载均衡(twenty-eight day)

官网&#xff1a; https://www.haproxy.com/ 自由及开放源代码软件 HAPrOxy是一个使用C语言编写的自由及开旅酒代码软性&#xff0c;其提供高可用性、负我均衡&#xff0c;以及基于TCP和HTTP的应用程座代理 HAProxy特别适用于那些负载特大的webi些站点通常又需要会话保挂或七层…

单片机中时钟源(Clock Source)和时基源(Timebase Source)和的联系和区别

问题描述 在单片机中&#xff0c;时钟源&#xff08;Clock Source&#xff09;和时基源&#xff08;Timebase Source&#xff09;是两个与时间相关的基本概念&#xff0c;它们在单片机的时钟系统设计中扮演着重要角色。 区别与联系 1.区别 1.1定义 时钟源&#xff1a;是单片机…

【C语言篇】编译和链接以及预处理介绍(上篇)

文章目录 前言翻译环境和运行环境翻译环境编译预处理&#xff08;预编译&#xff09;编译词法分析语法分析语义分析 汇编 链接 运行环境预处理&#xff08;预编译&#xff09;详解预定义符号#define定义常量#define定义宏带有副作用的宏参数宏替换的规则宏和函数的对比 写在最后…

【git】gitee 提交错误,如何回退

文章目录 查看提交记录设定退回到位置提交 查看提交记录 git log git log如下图所示共2次提交记录 最近一次是错误提交&#xff08;笔者提交是在错误的工作路径上传了&#xff09; 设定退回到位置 git reset --hard hash值 git reset --soft 83fcc380d5250599eca********…

rabbit消息队列

一&#xff1a;消息队列简介 1&#xff1a;主流的消息队列 目前主流的几大消息队列有&#xff1a;RabitMQ、ActiveMQ、RocketMQ、Kafka、ZeroMQ等&#xff0c;也有一些小众的比如Beanstalk&#xff0c;当然我们之前学过的Redis也可以实现消息队列的功能。 &#xff08;1&…

Android全面解析之Context机制(一) :初识Android context

什么是Context 回想一下最初学习Android开发的时候&#xff0c;第一用到context是什么时候&#xff1f;如果你跟我一样是通过郭霖的《第一行代码》来入门android&#xff0c;那么一般是Toast。Toast的常规用法是&#xff1a; Toast.makeText(this, "我是toast", To…