【C++第十课 - stack_queue】stack、queue的使用、适配器模型stack、queue和priority_queue的底层实现、deque

目录

  • 一、stack使用
    • 1、push
    • 2、pop
    • 3、empty
    • 4、top
    • 题目
      • 1、最小栈
      • 2、栈的压入、弹出序
      • 3、逆波兰表达式求值
  • 二、queue的使用
    • priority_queue
    • 习题
  • 三、适配器
    • stack的底层实现
    • queue的底层实现
    • priority_queue的底层实现
    • 仿函数/函数对象
    • 函数指针
  • 四、deque

一、stack使用

stack是个容器适配器
stack想要访问里面所有的数据必须pop和top,不能使用范围for

1、push

插入向量
在这里插入图片描述

	stack<int> s;s.push(1);s.push(2);s.push(3);s.push(4);

2、pop

移除栈顶数据
在这里插入图片描述

3、empty

stack为空返回true
stack非空返回false

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、top

取栈顶元素

题目

1、最小栈

https://leetcode.cn/problems/min-stack/
在这里插入图片描述
双栈解决
方案一
设计两个stack,一个stack存放数值,另一个stack存放最小值

存了这么多5有点浪费空间
改进方案二

在这里插入图片描述
方案二

_stpop的与_minst栈顶元素一样的时候,_minst也pop
存在的问题:当有好多个最小值是_minst要push进去多个,->改进:方案三

在这里插入图片描述

class MinStack {
public:MinStack() { }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;
};

方案三
在这里插入图片描述

2、栈的压入、弹出序

用栈来模拟入栈和出栈过程

(1)如果pushV当前入栈的值和popV当前出栈的值一样,pushV向后移一位,popV向后移一位
(2)如果pushV当前入栈的值和popV当前出栈的值不一样,分两种情况
第一种情况:如果栈顶元素与popV当前出栈元素一样,popv向后移一位,栈顶元素弹出
第二种情况:如果栈为空或栈顶元素与popV当前的出栈元素不一样,将pushV当前入栈元素压入栈中,pushV向后移一位

之后开始对栈中元素按照popV的顺序进行出栈,如果对不上就是False

简化:先入栈,再判断

1、入栈序列当前数据入栈
2、栈顶元素与出栈序列进行比较
(1)相等,出栈,出栈序列++
(2)不相等
2的结束标志,栈为空或不相等
所有的结束标志:入栈序列走完

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

3、逆波兰表达式求值

逆波兰表达式求值

前缀表达式(波兰)
所有的符号都是在要运算的操作数字的前面出现。例如 /++abcde
中缀表达式
所有的符号都是在要运算的操作数字的中间出现。例如(a+b+c
d)/e
后缀表达式(逆波兰)
所有的符号都是在要运算的操作数字的后面出现。例如 abcd*++e/

在这里插入图片描述

二、queue的使用

在这里插入图片描述

容器container默认是deque(双端队列)

在这里插入图片描述

priority_queue

不是先进先出,是按优先级出
底层是:堆
是适配器,不是容器了
compare是比较的函数

在这里插入图片描述
在这里插入图片描述

习题

在这里插入图片描述
方法一

在这里插入图片描述

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;queue<int> qlayer;vector<vector<int>> vv;int layer = 1;if(root){q.push(root);qlayer.push(layer);}while(!q.empty()){vector<int> v;while(qlayer.front() == layer ){TreeNode* cur = q.front();q.pop();v.push_back((*cur).val);if(cur->left){q.push(cur->left);qlayer.push(layer + 1);}if(cur->right){q.push(cur->right);qlayer.push(layer + 1);}qlayer.pop();}vv.push_back(v);++layer;}return vv;}
};

方法二

三、适配器

适配器就是一个设计模式
由容器(string、vector、list、deque)封装、转换而成的,底层数据的管理不是由自己负责的
默认容器:
stack -> deque
queue -> deque
priority_queue -> vector

stack的底层实现

站和队列的底层实现都是复用的容器(string、vector、list)

在这里插入图片描述

	template<class T, class Container = deque<T>>class stack{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
在这里插入代码片

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();}const T& front(){return _con.front();}const T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};

priority_queue的底层实现

在这里插入图片描述
是优先级队列,优先级高的先出,因此用堆进行实现

	template<class T, class Container = vector<T>>class priority_queue{public:void adjust_up(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (parent >= 0){if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up();}void adjust_down(){int parent = 0;int left = parent * 2 + 1; int right = parent * 2 + 2;int size = _con.size();while (left < size){int big = left;if (right < size && _con[right] > _con[left]){big = right;}if (_con[big] > _con[parent]){swap(_con[big], _con[parent]);parent = left;left = parent * 2 + 1;right = parent * 2 + 2;}else{break;}}}//优先出优先级高的void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down();}const T& top(){return _con[0];}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};

priority_queue里面用的仿函数–第三个模板参数

仿函数/函数对象

为了解决函数指针的缺陷
回调函数:这个函数已经写好了,在用到它的时候再去调它(C语言用这个)
Compare可以定义成成员对象,也可以在用的时候创建一个Compare com;
模板参数:传的是类型,编译的时候传递

namespace zyh
{template<class T>class less{public:bool operator()(T x, T y){return x < y;}};template<class T>class greater{public:bool operator()(T x, T y){return x > y;}};template<class T, class Container = vector<T>, class Compare = greater<T>>class priority_queue{public:void adjust_up(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (parent >= 0){if (_com(_con[child], _con[parent])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up();}void adjust_down(){int parent = 0;int left = parent * 2 + 1; int right = parent * 2 + 2;int size = _con.size();while (left < size){int big = left;if (right < size && _com(_con[right], _con[left])){big = right;}if (_com(_con[big], _con[parent])){swap(_con[big], _con[parent]);parent = left;left = parent * 2 + 1;right = parent * 2 + 2;}else{break;}}}//优先出优先级高的void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down();}const T& top(){return _con[0];}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;Compare _com;};
}

在这里插入图片描述
模板参数不仅能在类里面传递还能在函数里面传递
在这里插入图片描述

上面是类模板,只能穿仿函数。如果传函数指针,类里面也是将它转换成类型还是拿不到函数指针
下面是函数模板,可以传仿函数对象、函数指针。能传函数指针是因为,可以根据函数指针推出类型,同时参数那也可以得到函数指针。

函数指针

传递的是对象是参数变量,运行时传递的

在这里插入图片描述

四、deque

双端队列,但不是队列。就像优先级队列也不是队列

拥有list和vector的所有功能,尾插尾删、头插头删、[ ]
[ ]的效率没有vector的高

vector
优点:物理结构连续存储的优势
(1)下标随机访问
(2)缓存命中高
缺点:
(1)前面插入删除效率低
(2)扩容有消耗
list
优点:
(1)扩容没有消耗
(2)随机插入删除效率高
缺点:
(1)不支持下标随机访问
(2)缓存命中低

在这里插入图片描述

deque
优势:头插头删,尾插尾删很不错
不足:
随机访问效率没有vector高
访问第i个值,【假设保持每个buff一样大,都是10】
如果第一个buff不是从头开始的,不在第一个buff,那么i -= 第一个buff的数据个数
第i/10个buff中
在这个buff的第i%10位置
中间插入删除如何实现?
如果不需要保持每个buff一样大,只能挪动数据
如果不需要保持每个buff一样大,可以对当前buff,扩容或者挪动数据

结论
1、小标随机访问,效果不错,但是跟vector仍有差距
2、中间插入删除,效率差

如果一个适配器经常头插头删、尾插尾删 -> deque
如果少量的下标访问 -> 可以用deque
如果大量的下标访问 -> 需要用vector
如果中间插入删除 -> list

在这里插入图片描述

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

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

相关文章

聚焦大模型应用落地,2024全球数字经济大会人工智能专题论坛在京举办

7月1日下午&#xff0c;2024全球数字经济大会人工智能专题论坛在中关村国家自主创新示范区会议中心举办。论坛紧扣大模型应用落地这一热点&#xff0c;以“应用即未来——大模型赋能千行百业&#xff0c;新生态拥抱产业未来”为主题&#xff0c;备受社会各界关注。 一、北京已…

Windows中Git的使用(2024最新版)

Windows中Git的使用 获取ssh keys本地绑定邮箱初始化本地仓库添加到本地缓存区提交到本地缓存区切换本地分支为main关联远程分支推送到GitHub查看推送日志 Git 2020年发布了新的默认分支名称"main"&#xff0c;取代了"master"作为主分支的名称。操作有了些…

【已解决】: fatal error: cuda_runtime_api.h: No such file or directory

既然他找不到&#xff0c;我们就把路径给他写清楚&#xff01; 检查自己是不是有这个文件&#xff1a; 去路径/usr/local下&#xff0c;使用命令查询是否拥有该文件&#xff1a; find . -name cuda_runtime_api.h结果&#xff1a; 因为我要使用的是cuda-11.3&#xff0c;因…

【Spring Cloud】一个例程快速了解网关Gateway的使用

Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式&#xff0c;并为它们提供一些网关基本功能&#xff0c;例如&…

自用款 复制粘贴工具 Paste macOS电脑适配

Paste是一款专为Mac和iOS用户设计的剪贴板管理工具&#xff0c;它提供了强大的剪贴板增强功能。Paste能够实时记录用户复制和剪切的内容&#xff0c;包括文本、图片、链接等多种数据类型&#xff0c;并形成一个可视化的剪贴板历史记录&#xff0c;方便用户随时访问和检索。此外…

【论文通读】RuleR: Improving LLM Controllability by Rule-based Data Recycling

RuleR: Improving LLM Controllability by Rule-based Data Recycling 前言AbstractMotivationSolutionMethodExperimentsConclusion 前言 一篇关于提升LLMs输出可控性的短文&#xff0c;对SFT数据以规则的方式进行增强&#xff0c;从而提升SFT数据的质量&#xff0c;进而间接帮…

uniapp如何隐藏默认的页面头部导航栏,uniapp开发小程序如何隐藏默认的页面头部导航栏

uniapp如何隐藏默认的页面头部导航栏 隐藏后 在pages.json文件中插入 在uni-app中&#xff0c;设置navigationStyle为custom来自定义导航栏&#xff0c;可以隐藏默认的头部了。 {"path": "pages/index/index","name": "index",&qu…

IDEA 开发工具

IDEA 开发工具 IDEA软件激活新建项目新建project 运行调试 IDEA软件激活 访问激活码网进入带*的域名下载并解压左上角的zip包先执行sh uninstall.sh&#xff0c;再执行sh install.sh在带*的网页中复制并使用激活码code 新建项目 新建project file》New〉Project》New Proje…

06.C2W1.Auto-correct

往期文章请点这里 目录 OverviewAutocorrectWhat is autocorrect?How it works Building the modelMinimum edit distanceMinimum edit distance algorithmMinimum edit distance Part 2Minimum edit distance Part 3 往期文章请点 这里 Overview 本周学习目标&#xff1a;…

嵌入式鸿蒙系统openharmony编译方法详解

大家好,时光如梭,今天主要给大家分享一下,鸿蒙系统的使用方法,以及源码该如何编译,其中要注意的细节有哪些? 第一:OpenHarmony系统简介 OpenHarmony 是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目, 目标是面向全场景、全连接、全智能时代,基于…

数据结构之“队列”(全方位认识)

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;数据结构 前言 上期博客介绍了” 栈 “这个数据结构&#xff0c;他具有先进后出的特点。本期介绍“ 队列 ”这个数据结构&#xff0c;他具有先进先出的特点。 目录…

秋招提前批面试经验分享(上)

⭐️感谢点开文章&#x1f44b;&#xff0c;欢迎来到我的微信公众号&#xff01;我是恒心&#x1f60a; 一位热爱技术分享的博主。如果觉得本文能帮到您&#xff0c;劳烦点个赞、在看支持一下哈&#x1f44d;&#xff01; ⭐️我叫恒心&#xff0c;一名喜欢书写博客的研究生在读…

【Java EE】Spring Boot配置文件

Spring Boot配置文件 一、配置文件的分类 一共有三类&#xff0c;分别是 properties, yml, yaml&#xff0c;其中properties相当于是老版&#xff0c;yml是yaml的缩写&#xff0c;这两个相当于新版。 二、配置文件的语法 1. properties 语法的构成是以"." 为分隔…

PingCAP 成为全球数据库管理系统市场增速最快的厂商

近日&#xff0c;Gartner 发布的《Market Share Analysis: Database Management Systems, Worldwide, 2023》&#xff08;2024 年 6 月&#xff09;报告显示&#xff1a;“2023 年全球数据库管理系统&#xff08;DBMS&#xff09;市场的增长率为 13.4%&#xff0c;略低于去年的…

【Spring AOP 源码解析前篇】什么是 AOP | 通知类型 | 切点表达式| AOP 如何使用

前言&#xff08;关于源码航行&#xff09; 在准备面试和学习的过程中&#xff0c;我阅读了还算多的源码&#xff0c;比如 JUC、Spring、MyBatis&#xff0c;收获了很多代码的设计思想&#xff0c;也对平时调用的 API 有了更深入的理解&#xff1b;但过多散乱的笔记给我的整理…

【Linux系统编程】文件系统

介绍&#xff1a; 文件系统是操作系统中负责管理和存储文件信息的软件结构&#xff0c;它组织和管理磁盘上的文件和目录&#xff0c;并定义了文件的存储结构。 Linux文件系统采用树状结构&#xff0c;只有一个根目录&#xff08;用“/”表示&#xff09;&#xff0c;其中含有下…

【Linux】:程序地址空间

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关Linux程序地址空间的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从…

GD32实战篇-双向数控BUCK-BOOST-BUCK降压理论基础

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 向上代码兼容GD32F450ZGT6中使用 后续项目主要在下面该专栏中发布&#xff1a; https://blog.csdn.net/qq_62316532/category_12608431.html?spm1001.2014.3001.5482 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转…

【驱动篇】龙芯LS2K0300之ADC驱动

实验目的 由于LS2K0300久久派开发板4.19内核还没有现成可用的ADC驱动&#xff0c;但是龙芯官方的5.10内核已经提供了ADC驱动&#xff0c;想要在4.19内核使用ADC就要参考5.10内核移植驱动&#xff0c;本次实验主要是关于ADC驱动的移植和使用 驱动移植 主要的驱动代码主要有3个…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十二)-管道、环境变量、常用命令

大致介绍了一下管道、环境变量、一些常用的基本命令&#xff0c;可以当作学习笔记收藏学习一下&#xff01;&#xff01;&#xff01; 文章目录 前言 一、管道 二、环境变量 1.概念 2.查看 3.修改 4.常用环境变量 三、系统状况 总结 前言 大致介绍了一下管道、环境变量、一些常…