C++:栈(stack)、队列(queue)、优先级队列(priority_queue)

news2024/11/18 5:37:25

hello,各位小伙伴,本篇文章跟大家一起学习《C++:栈(stack)和队列(queue)》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !

文章目录

    • :maple_leaf:栈---stack
    • :maple_leaf:栈---stack题目:最小栈(来自leetcode)
      • :leaves:如果途中出栈
      • :leaves:答案代码
    • :maple_leaf:栈的压入、弹出序列
      • :leaves:答案代码
    • :maple_leaf:队列---queue
    • :maple_leaf:优先级队列---priority_queue
      • :leaves:优先级队列使用
      • :leaves:注意

🍁栈—stack

template <class T, class Container = deque > class stack;
栈是一种容器适配器,专门设计用于在后进先出(后进先出)上下文中操作,其中元素仅从容器的一端插入和提取。

栈—stack被实现为容器适配器,它是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素。元素是从特定容器的“后部”推/弹出的,即堆栈的顶部。底层容器可以是任何标准容器类模板或某些其他专门设计的容器类。

容器应支持以下操作:

  • empty
  • size
  • back
  • push_back
  • pop_back

标准容器类vector、deque和list满足这些要求。默认情况下,如果没有为特定堆栈类实例化指定容器类,则使用标准容器deque

是后进先出的底层容器,是一个模板类,其逻辑结构:

在这里插入图片描述

栈的成员函数以及功能:
在这里插入图片描述

🍁栈—stack题目:最小栈(来自leetcode)

题目在这:最小栈

在这里插入图片描述
题目会对该栈进行压栈和出栈,要我们随时查找栈里最小的元素,并且规定在常数时间里检索出来并返回。

根据栈的性质—LIFO(后进先出):
设计两个栈

  • _push负责接受所有操作(1.压栈、2.出栈)
  • s另一个负责接收最小元素(1.当s为空或者栈顶元素 >= _push压栈元素时压栈,2.当_push出栈元素 == s栈顶元素时出栈,3.获取栈顶元素)
  • 测试例子

在这里插入图片描述

第一步操作:对_push栈进行压栈(元素为-2),由于一开始s栈为空,所以s进行压栈:
在这里插入图片描述
第二步操作:对_push栈进行压栈(元素为0),由于0 > s的栈顶元素 -2,所以s栈不进行操作:
在这里插入图片描述
第三步操作:对_push栈进行压栈(元素为-3),由于-3 < s的栈顶元素 -2,所以s栈进行压栈操作:
在这里插入图片描述
第四步操作:minStack.getMin();
返回s栈的栈顶元素 -> -3

🍃如果途中出栈

上述例子,在第四步操作minStack.getMin();_push出栈一次,由于_push出栈元素等于s栈顶元素,所以s也跟着出栈,最后返回结果是-2
在这里插入图片描述

🍃答案代码

class MinStack {
public:
    MinStack() {

    }
    
    void push(int val) {
        s.push(val);
        if(_push.empty() || _push.top()>=val)
        {
            _push.push(val);
        }
    }
    
    void pop() {
        int tmp = s.top();
        s.pop();
        if(_push.top() == tmp)
        {
            _push.pop();
        }
    }
    
    int top() {
        return s.top();
    }
    
    int getMin() {
        return _push.top();
    }
    stack<int> _push;
    stack<int> s;
};

通过:
在这里插入图片描述

🍁栈的压入、弹出序列

题目在这:栈的压入、弹出序列
在这里插入图片描述
题目给出两个序列vector<int>& pushV, vector<int>& popV,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。

注意:题目说明压栈的所有数字都不相等!
那么我们可以设计一个栈_push,通过模拟出栈来解决这个问题。

int popi = 0;
int pushi = 0;
int len = popV.size();
if(len == 0)// 当队列为空时,返回true
return true;

遍历两个队列vector<int>& pushV, vector<int>& popV

  1. pushV[pushi] != popV[popi]时,那么说明并没有出栈,只有压栈,那么_push进行压栈操作:
    while循环来控制
while(pushi < len)
if(pushV[pushi] != popV[popi])
{
    _push.push(pushV[pushi]);
    ++pushi;
}
  1. pushV[pushi] == popV[popi]时,那么说明并存在出栈,先压栈后出栈,那么_push进行压栈出栈操作,出栈结束后还要判断_push栈顶元素是否等于popV[popi],如果相等则继续出栈(注意,此时_push不能为空,_push为空退出判断,popi > len说明出栈任务结束,退出判断):
_push.push(pushV[pushi]);// 先压栈
++pushi;
while(!_push.empty() && popi < len 
&& _push.top() == popV[popi])
{
    _push.pop();
    ++popi;
}
  1. while(pushi < len)结束,最后进行判断第二个序列是否可能为该栈的弹出顺序。很简单,判断_push是否为空或者popi 是否等于len即可。

🍃答案代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pushV int整型vector 
     * @param popV int整型vector 
     * @return bool布尔型
     */
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
        // write code here
        int popi = 0;
        int pushi = 0;
        int len = popV.size();
        if(len == 0)
        return true;
        while(pushi < len)
        {
            if(pushV[pushi] != popV[popi])
            {
                _push.push(pushV[pushi]);
                ++pushi;
            }
            else
            {
                _push.push(pushV[pushi]);
                ++pushi;
                while(!_push.empty() && popi < len 
                && _push.top() == popV[popi])
                {
                    
                    _push.pop();
                    ++popi;
                }
            }
        }
        return popi == len;
     // return _push.empty();
    }
    stack<int> _push;
};

在这里插入图片描述

🍁队列—queue

template <class T, class Container = deque > class queue;
队列是一种容器适配器,专门设计用于在 FIFO 上下文(先进先出)中操作,其中元素被插入到容器的一端并从另一端提取。

队列被实现为容器适配器,它们是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素。元素被推入特定容器的后面并从其前面弹出。

底层容器可以是标准容器类模板之一或一些其他专门设计的容器类。该底层容器至少应支持以下操作:

  • empty
  • size
  • front
  • back
  • push_back
  • pop_front

标准容器类 deque 和 list 满足这些要求。默认情况下,如果没有为特定队列类实例化指定容器类,则使用标准容器双端队列。

  • 逻辑图
    在这里插入图片描述
    队列的成员函数及其功能
    在这里插入图片描述

🍁优先级队列—priority_queue

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

🍃优先级队列使用

template <class T, class Container = vector, class Compare = less > class priority_queue;

在这里插入图片描述

🍃注意

  • priority_queue第三个参数有缺省值less,所以priority_queue默认是大堆,如果要建小堆,将第三个模板参数换成greater比较方式,如:
vector<int> v{3,2,7,6,0,4,1,9,8,5};
priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
cout << q2.top() << endl;
  • 如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供 > 或者 < 的重载。
    像是Date日期类的比较(年、月、日)。

你学会了吗?
好啦,本章对于《C++:栈(stack)和队列(queue)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

如你喜欢,点点赞就是对我的支持,感谢感谢!!!

请添加图片描述

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

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

相关文章

Spring Cloud系列——使用Sentinel进行微服务保护

文章目录 一、引言1. 雪崩问题的产生原因2. 解决雪崩问题的思路 二、微服务保护1. 服务保护方案1.1 请求限流1.2 线程隔离1.3 服务熔断 2. Sentinel2.1 安装2.2 微服务整合2.2.1 请求限流2.2.2 线程隔离①OpenFeign整合Sentinel②配置线程隔离 2.2.3 服务熔断①编写降级逻辑②配…

队列的讲解与实现

这里写目录标题 一、队列的概念及结构二、队列的实现(使用VS2022的C语言)1.初始化、销毁2.入队、出队3.返回队头元素、返回队尾元素、判空、返回有效元素个数 三、完整 Queue.c 源代码 一、队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端…

网络空间安全数学基础·同余式

6.1 剩余系&#xff08;掌握&#xff09; 6.2 同余式概念与一次同余式&#xff08;熟练&#xff09; 6.3 中国剩余定理&#xff08;熟练&#xff09; 6.1 剩余系 设m是正整数&#xff0c;模m同余的全体整数是一个模m剩余类&#xff0c;即可表示为a qmr&#xff0c; 0≤r<…

在推荐四款软件卸载工具,让流氓软件无处遁形

Revo Uninstaller Revo Uninstaller是一款电脑软件、浏览器插件卸载软件&#xff0c;目前已经有了17年的历史了。可以扫描所有window用户卸载软件后的残留物&#xff0c;并及时清理&#xff0c;避免占用电脑空间。 Revo Uninstaller可以通过命令行卸载软件&#xff0c;可以快速…

python数据分析-问卷数据分析(地理课)

学生问卷 分析学生背景&#xff1a;班级分布、每周地理课数量、地理成绩分布 根据问卷&#xff0c;可以知道&#xff1a; 班级分布&#xff1a; 七年级有118名学生。 八年级有107名学生。 每周地理课的数量&#xff1a; 有28名学生每周有1节地理课。 有99名学生每周有2…

dots_image 增强图像中的圆点特征

dots_image 增强图像中的圆点特征 1. dot_image 有什么用途&#xff1f;2. 点状字符的特征增强3. Halcon代码 1. dot_image 有什么用途&#xff1f; Enhance circular dots in an image. 这个算子可以增强图像中的圆点特征&#xff0c;例如下面的例子。 2. 点状字符的特征增强…

有待挖掘的金矿:大模型的幻觉之境

人工智能正在迅速变得无处不在&#xff0c;在科学和学术研究中&#xff0c;自回归的大型语言模型&#xff08;LLM&#xff09;走在了前列。自从LLM的概念被整合到自然语言处理&#xff08;NLP&#xff09;的讨论中以来&#xff0c;LLM中的幻觉现象一直被广泛视为一个显著的社会…

CAD二次开发(8)-探索实现不重启CAD进行热部署代码

最近在研究CAD二次开发过程中&#xff0c;调试代码的过程中&#xff0c;需要频繁地重启CAD&#xff0c;非常浪费我们的开发时间&#xff0c;所以我就一直在想&#xff0c;怎么可以实现在不每次重启代码和CAD的情况下&#xff0c;实现代码的热部署效果。 我找到的方式&#xff…

论文阅读 A Distributional Framework for Data Valuation

本论文解决的问题 量化数据价值&#xff08;机器学习模型训练中各个数据点的贡献&#xff09; 避免数据价值受到其所处数据集的影响&#xff0c;使数据点的估值更加稳定、一致 变量假设 假设 D 表示一个在全集 Z 上的数据分布。对于监督学习问题&#xff0c;我们通常认为 Z…

高考志愿填报有哪些技巧和方法

一年一度高考季&#xff0c;又高考志愿填报的时侯了。高考志愿填报的时侯&#xff0c;需要考虑的因素比较多&#xff0c;有的同学觉是离家越远越好&#xff0c;要放飞自我&#xff0c;家长再也管不了我了。有的同学觉得专业比学校牌子重要&#xff0c;只要报个好专业&#xff0…

服务监控-微服务小白入门(5)

背景 什么是服务监控 监视当前系统应用状态、内存、线程、堆栈、日志等等相关信息&#xff0c;主要目的在服务出现问题或者快要出现问题时能够准确快速地发现以减小影响范围。 为什么要使用服务监控 服务监控在微服务改造过程中的重要性不言而喻&#xff0c;没有强大的监控…

【WP】猿人学_16_js逆向_window蜜罐

https://match.yuanrenxue.cn/match/16 抓包分析 荷载一个加密参数&#xff0c;一个时间戳 时间: 2024-06-07 15:52:31时间戳: 1717746751 1717746751000时间戳和现在对得上&#xff0c;直接生成就行。 追栈 追栈找m的生成位置。 点进去打断点&#xff0c;重新点击其他…

Java 8 中的 Stream API,用于处理集合数据

Java 8 引入了 Stream API&#xff0c;使得处理集合数据变得更加简洁和高效。Stream API 允许开发者以声明式编程风格操作数据集合&#xff0c;而不是使用传统的迭代和条件语句。 一、基本概念 1.1 什么是 Stream Stream 是 Java 8 中的一个新抽象&#xff0c;它允许对集合数…

Java学习笔记(六):Array List、学生管理系统、学生管理系统升级版

目录 一、ArrayList 1.1集合和数组的优势对比&#xff1a; 1.2 ArrayList类概述 1.3 ArrayList类常用方法 1.3.1 构造方法 1.3.2 成员方法 1.4 ArrayList存储字符串并遍历 1.5 ArrayList存储学生对象并遍历 1.6 查找用户的索引 1.7 添加手机对象并返回要求的数据 二…

用 Notepad++ 写 Java 程序

安装包 百度网盘 提取码&#xff1a;6666 安装步骤 双击安装包开始安装。 安装完成&#xff1a; 配置编码 用 NotePad 写 Java 程序时&#xff0c;需要设置编码。 在 设置&#xff0c;首选项&#xff0c;新建 中进行设置&#xff0c;可以对每一个新建的文件起作用。 Note…

【Flutter】 TextField限制长度时, 第三方手写输入法、ios原始拼音输入法输入被吞问题

问题描述 TextField限制长度时&#xff0c; 当你的输入字符长度已经到了最大值-1时&#xff0c;使用第三方手写输入法或者ios原生拼音输入法输入liang&#xff08;什么拼音都行&#xff0c;这里只是举例&#xff09;&#xff0c;输到i那么li都会消失。 原因分析 这是因为第三…

nginx配置WebSocket参数wss连接

目录 一、原文连接 二、 配置参数 三、实践 四、重启nginx 五、连接websocket 一、原文连接 nginx配置websocket支持wss-腾讯云开发者社区-腾讯云 二、 配置参数 map $http_upgrade $connection_upgrade { default upgrade; close; } upstream websocket { se…

PostgreSQL基础(九):PostgreSQL的事务介绍

文章目录 PostgreSQL的事务介绍 一、什么是ACID&#xff08;常识&#xff09; 二、事务的基本使用 三、保存点&#xff08;了解&#xff09; PostgreSQL的事务介绍 一、什么是ACID&#xff08;常识&#xff09; 在日常操作中&#xff0c;对于一组相关操作&#xff0c;通常…

基于t-SNE的泰坦尼克号数据集降维

目录 1. 作者介绍2. 算法介绍2.1 t-SNE介绍2.2.SNE基本原理2.3.拥挤问题2.4.t-SNE基本原理2.5.t-SNE算法过程 3. 泰坦尼克号数据集降维实验3.1.数据集介绍3.2 任务介绍3.3 代码实现3.4 实验结果 参考连接 1. 作者介绍 刘方星&#xff0c;男&#xff0c;西安工程大学电子信息学…

vue3 监听器,组合式API的watch用法

watch函数 在组合式 API 中&#xff0c;我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数 watch(ref,callback&#xff08;newValue,oldValue&#xff09;&#xff0c;option:{}) ref:被监听的响应式量&#xff0c;可以是一个 ref (包括计算属性)、一个响应式…