C++STL的stack和queue(超详解)

文章目录

  • 前言
  • stack
  • 栈的题目
    • 最小栈
    • JZ31 栈的压入、弹出序列
  • stack的模拟实现
  • queue的模拟实现

前言

栈和队列这一块其实有数据结构的基础,学起来非常简单。

stack

在这里插入图片描述
栈的成员函数就这么写,除了emplace其他都已经非常熟悉了。

stack没有迭代器吗?
没有,因为栈已经不是容器了,它是容器适配器。给它一个迭代器还能保证先进先出这些吗?不能。

stack跟我们之前学的list其实很不太一样。
在这里插入图片描述
模板参数不同。
在这里插入图片描述

先快速用一下stack,让它跑起来。

void test_stack()
{stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;
}

在这里插入图片描述

栈的题目

最小栈

接下来我们做题来加深一下对stack的理解。
最小栈

在这里插入图片描述

思路

首先定义两个栈,一个栈是正常的栈,实现正常的操作。
我们用另一个栈是最小栈,来实现O(1)检索到最小元素的栈。

这里要不要写那4个默认成员函数?
在这里插入图片描述
不用。

push
如果是空栈或者需要push的数据小于最小栈栈顶元素,我们就push.否则最小栈不做处理。
在这里插入图片描述

注意,如果需要push的数据等于栈顶元素也要push,否则pop的时候会把最小值也pop掉

pop
如果最小栈的栈顶元素和正常栈的栈顶元素相等我们就pop

class MinStack {
public:
//不用写MinStack() {}void push(int val) {_st.push(val);if (_minst.empty() || val <= _minst.top()){_minst.push(val);}}void pop() {if (_minst.top() == _st.top()){_minst.pop();}_st.pop();}int top() {return _st.top();}int getMin() {return _minst.top();}
private:stack<int> _st;stack<int> _minst;
};

优化
在这里插入图片描述
如果是这样那不是很浪费。

可以这样优化,每个地方不是存一个值而是存一个结构。
在这里插入图片描述
给大家看一下结构,具体实现就先不实现了。

stack<int> _st;
struct Data
{int _val;int _count;
}
stack<Date> _minst;

这就是模板的好处,如果没有模板,那自己还需要再写一个栈。

JZ31 栈的压入、弹出序列

栈的压入、弹出序列
在这里插入图片描述
在这里插入图片描述
这道题稍有不慎就会写的很复杂,如果想清楚了也挺简单的。

在这里插入图片描述
不匹配的一种情况
在这里插入图片描述

思路
这道题有很多种思路,最简单的就是用一个栈模拟入栈出栈的过程。
如果能模拟出来就匹配了,如果模拟不出来就不行。

所以我们的重点在于模拟这个栈。

先要第一个出4,那就入数据1234。只要不匹配就入数据。
在这里插入图片描述

下一个出5,不匹配继续入
在这里插入图片描述
再看下一个要出的数据是不是栈顶的元素,是就直接出。
在这里插入图片描述
如果能把入栈序列走完,出栈序列也走完,那就匹配了。

在这里插入图片描述
以pushi为主要的,因为popi不一定能走到结尾。
第一步,入栈
第二步,判断是否要出栈(注意不一定只出一次)

在这里插入图片描述

凡是这样写一定要小心,栈出了一个,然后栈空了。

空栈调用会报错。

怎么样匹配?
两种方式
1.popi走到尾了
2.栈为空
在这里插入图片描述

stack的模拟实现

栈的实现有两种方式。
1.数组栈,尾部当作栈顶。
2.链表栈,头部当作栈顶。
数组栈更有优势一点。

传统的写法,无非就是搞一个数组,不够了就扩容。
我们这里用一个适配器的玩法。
在这里插入图片描述

适配器的本质是什么?
现实生活中,我们的充电头也叫电源适配器。电源适配器是干嘛的?是生产电源的吗?
其实是用来变压的。
所以适配器的本质是用来转换的,把原来的东西给转换过来。

容器适配器,它不是自己存储数据,它是把已有的东西进行转换。

我们要实现一个顺序栈,链表栈,我们需要自己写吗?
我们可以拿一个已有的容器封装,这样写起来更简单。
在这里插入图片描述
但是这还不是适配,还要转换。
再增加一个模板参数,Container,他具体是啥我也不知道,但是它肯定是符合我们要求的容器。
在这里插入图片描述

要实现顺序栈,传vector.
要实现链表栈,传list.

namespace but
{template<class T, class Container>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://vector<T> _v;Container _con;};void test_stack(){stack<int, vector<int>> st;//顺序栈//stack<int, list<int>> st;//链式栈//stack<int> st //缺省类型st.push(1);st.push(2);st.push(3);st.push(4);while (!st.empty()){cout << st.top() << " ";st.pop();}cout << endl;}
}

还可以给缺省类型。

template<class T, class Container= vector<T>>

函数传参如果不从右往左会有歧义。
在这里插入图片描述
假设传两个参数,你就不知道传给谁了。

queue的模拟实现

快速手搓。

namespace but
{template<class T, class Container = list<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;};void test_queue(){queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << " ";q.pop();}cout << endl;}
}

队列还能不能用vector适配?
队列要头插尾删,vector不支持头删。如果强行用erase,效率有点低。

在实现队列的头文件里没有包括vector和list为什么还能用?
如果编译它是会报错的,但是编译器不编译它。.h是不会被编译的,它是在包含的地方展开,然后编译器向上找。
在这里插入图片描述
这样写就不行了
在这里插入图片描述

为什么?
因为c和c++编译的时候都有一个特点,他不会在整个文件里面找。一展开像上去找,找不到vector,因为vector在std里面,又没有指定std.

在命名空间里只有指定或者展开才能找到。

从string开始,只写.h,不写cpp,为什么?
从规范角度来说肯定要写的,模板不能这么写,这样写出来是有问题的。
你可以尝试用声明和定义分离写一下stack。
在这里插入图片描述
为什么又找不到vector?
stack.cpp这里展开.h,又找不到vector.
在这里插入图片描述

声明和定义分离会导致很多问题,他会导致链接错误。链接错误就是找不到定义。
模板不能声明和定义分离。

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

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

相关文章

【Linux】锁的简单封装以及原理解析

文章目录 一、锁的原理过程1&#xff1a;过程2过程3过程4 二、 锁的简单封装1.LockGuard.hpp2.使用1.正常锁的使用2.使用封装后的 总结 一、锁的原理 为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条…

锂电池基础知识及管理方式总结

这两天在排查一个锂电池无法充电的问题&#xff0c;用的是电池管理芯片BQ25713&#xff0c;网上相关的资料也很少&#xff0c;查看数据手册时&#xff0c;里面也有很多术语参数等不是很理解&#xff0c;所以&#xff0c;在此对锂电池的基础知识做个简单的总结&#xff0c;方面后…

python自动化运维快速入门,python自动化运维教程

大家好&#xff0c;给大家分享一下python自动化运维需要掌握的技能&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 面向学员 熟练使用计算机&#xff0c;对Windows、Linux 有一点了解从业职或在校学生 对目前从事互联网运维&#xff0c;想…

【MySQL】:表的约束(上)

表的约束 一.非空约束二.default约束三.列描述四.zerofill五.主键1.单个主键2.复合主键 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。比如有…

Kubernetes实战(九)-kubeadm安装k8s集群

1 环境准备 1.1 主机信息 iphostname10.220.43.203master10.220.43.204node1 1.2 系统信息 $ cat /etc/redhat-release Alibaba Cloud Linux (Aliyun Linux) release 2.1903 LTS (Hunting Beagle) 2 部署准备 master/与slave主机均需要设置。 2.1 设置主机名 # master h…

做题笔记:SQL Sever 方式做牛客SQL的题目--查询每天刷题通过数最多的前二名用户

----查询每天刷题通过数最多的前二名用户id和刷题数 现有牛客刷题表questions_pass_record&#xff0c;请查询每天刷题通过数最多的前二名用户id和刷题数&#xff0c;输出按照日期升序排序&#xff0c;查询返回结果名称和顺序为&#xff1a; date|user_id|pass_count 表单创建…

论文润色突显研究亮点 papergpt

大家好&#xff0c;今天来聊聊论文润色突显研究亮点&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 标题&#xff1a;论文润色突显研究亮点――提升论文吸引力的关键步骤 一、引言 在学术研究中&#x…

docker学习(八、mysql8.2主从复制遇到的问题)

在我配置主从复制的时候&#xff0c;遇到了一直connecting的问题。 起初可能是我ip配置的不对&#xff0c;slave_io_running一直connecting。&#xff08;我的环境&#xff1a;windows中安装了wsl&#xff0c;是ubuntu环境的&#xff0c;在wsl中装了miniconda&#xff0c;mini…

Matter分析与安全验证

本文作者&#xff1a;杉木涂鸦智能安全实验室 什么是matter Matter是一项智能家居的开源标准&#xff0c;由连接标准联盟制定、认证、推广&#xff0c;该标准基于互联网协议&#xff08;IP&#xff09;&#xff0c;遵循该标准的智能家居设备、移动应用程序和云服务能够进行互…

Java基础语法之继承

为什么要继承 会发现&#xff0c;狗和猫只有叫声不同&#xff0c;因为它们都是动物&#xff0c;会有相同的属性和行为&#xff0c;所以它们可以继承animla类 如何继承 用到extends关键字 这样就会简化好多 注意 1.Animal称为父类/超类/基类&#xff1b;dog&#xff0c;cat称…

linux下sys目录与proc目录的作用

sys目录作用 在Linux系统中&#xff0c;/sys目录是一个特殊的虚拟文件系统&#xff08;sysfs&#xff09;&#xff0c;用于提供对内核和设备的运行时信息的访问。它是在内核中运行的驱动程序和子系统的接口&#xff0c;可以用于获取和配置系统的硬件和内核信息。 以下是/sys目…

提升测试工具开发的思考

本文针对测试部效率提升测试工具开发、管理、维护暴露出来的问题的一些思考以及一些个人改进观点。 写在前面 本文提到的效率提升测试工具不是指的部门中固有的自动化测试工具&#xff0c;这里提到的测试工具统一指测试人员在工作之余自主开发用于期望替代重复、繁琐、耗时的手…

sylar高性能服务器-配置(P12-p14)内容记录

文章目录 p12&#xff1a;复杂类型解析一、方法函数二、结果展示 p13&#xff1a;复杂类型解析完善一、方法函数二、结果展示 p14&#xff1a;自定义类型解析一、方法函数二、小结 p12&#xff1a;复杂类型解析 ​ 本节内容主要针对完了配置类中对于复杂类型的转换。之前只实现…

最近面试了一位5年的测试,一问三不知,还反怼我...

最近看了很多简历&#xff0c;很多候选人年限不小&#xff0c;但是做的都是一些非常传统的项目&#xff0c;想着也不能通过简历就直接否定一个人&#xff0c;何况现在大环境越来 越难&#xff0c;大家找工作也不容易&#xff0c;于是就打算见一见。 在沟通中发现&#xff0c;由…

Linux高级管理--安装MySQL数据库系统

MySQL服务基础 MySQL.是一个真正的多线程、多用户的SQL数据库服务&#xff0c;凭借其高性能、高可靠和易于使 用的特性&#xff0c;成为服务器领域中最受欢迎的开源数据库系统。在2008年以前&#xff0c;MySOL项目由MySQL AB公司进行开发&#xff0c;发布和支持&#xff0c;之后…

产品表结构分析

一个项目之中&#xff0c;会有很多数据&#xff0c;众多数据之间也存在这各种关系&#xff0c;如何依据这些关系设计出更符合实际且适合的表及之间的关联关系也是我们所必须学习的 一、常见部门表结构分析 几乎所有框架里面都有一张部门表&#xff0c;我们先来看一下他的结构&…

逆向思考 C. Fence Painting

Problem - 1481C - Codeforces 思路&#xff1a;逆序考虑&#xff0c;因为每一块木板都是被最后一次粉刷所决定的。 从后往前开始&#xff0c;对于 c i c_i ci​来说&#xff0c; 如果这个颜色还有没有涂的木板&#xff0c;那么涂到其中一个木板即可如果这个颜色下没有未涂的…

使用selenium的edge浏览器登录某为

互联网上基本都是某哥的用法&#xff0c;其实edge和某哥的用法是一样的就有一下参数不一样。 一、运行环境 Python&#xff1a;3.7 Selenium&#xff1a;4.11.2 Edge&#xff1a;版本 120.0.2210.61 (正式版本) (64 位) 二、执行代码 from time import sleepfrom selenium…

GB28181学习(十八)——图像抓拍

前言 本文主要介绍图像抓拍功能&#xff0c;通过自研的sip库&#xff08;mysipsdk.dll&#xff09;对接真实设备&#xff0c;使用http方式实现图像数据传输&#xff0c;最终达到图像抓拍与保存的目的。 基本要求 图像格式宜使用JPEG&#xff1b;图像分辨率宜采用与主码流相同…

【JMeter】使用nmon进行性能资源监控

一、前言 ​ 在工作中可能会遇到需要在压测的时候对Linux服务器进行性能资源监控的情况。这时可以用nmon来对服务器进行监控。 二、nmon的下载安装 1.查看系统信息 shell cat /etc/os-release结果为 shell PRETTY_NAME"Debian GNU/Linux 12 (bookworm)" NAME&qu…