c++的STL(7) -- stack

stack容器概述

  • stack容器其实是实现了一种和栈相同结构的容器。  

如图,栈这种结构有两端: 栈底和栈顶。  特殊之处在于,这种结构,我们对数据的操作(删除数据,修改数据,查询数据,添加数据)只能在一端进行(栈顶)。是一种后进先出的结构。


例如:  当我们添加数据的时候,只能从栈顶的位置添加数据。而我们删除数据的时候也只能从栈顶的位置删除。

stack容器的实现 

stack也是一个模板类:

template <class _Ty, class _Container = deque<_Ty>>  class stack {}

上面就是其模板的类型参数,很明显,它接受两个参数,一个是其存储数据的类型,一个则是一个容器类型。 

为什么要接受一个容器类型呢? 

因为stack容器其实是在我们之前学习的vector,deque,list容器的基础上,实现了其它的功能,其内部存储数据还是使用这三个容器(其内部定义了容器的对象)。


为什么要这么做呢?

因为,我们之前学习过的容器功能已经很强大了,但是在某些场景下它们的功能可能并不适用,但是重新开发新的容器也并不高效。

所以我们可以根据我们已有的容器,通过相应的封装和组合,实现对应的功能。

stack就是这样的一个容器,它在vector,deque,list这三个容器的基础之上进行了封装,实现了符合栈结构的容器。(基于这种原理,我们也可以实现我们自己的容器)  --  对于stack而言这三个容器为基础容器。

stack中的函数 

表 stack容器支持的成员函数
成员函数功能
empty()当 stack 栈中没有元素时,该成员函数返回 true;反之,返回 false。
size()返回 stack 栈中存储元素的个数。
top()返回一个栈顶元素的引用,类型为 T&。如果栈为空,程序会报错。
push(const T& val)先复制 val,再将 val 副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。
push(T&& obj)以移动元素的方式将其压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。
pop()弹出栈顶元素。
emplace(arg...)arg... 可以是一个参数,也可以是多个参数,但它们都只用于构造一个对象,并在栈顶直接生成该对象,作为新的栈顶元素。
swap(stack<T> & other_stack)将两个 stack 适配器中的元素进行互换,需要注意的是,进行互换的 2 个 stack 适配器中存储的元素类型以及底层采用的基础容器类型,都必须相同。

注意: 我们前面说到,理论上stack可以使用vector,list,deque三个容器存储数据,但是具体情况还需要根据stack所要实现的功能来定。(就是看实现stack所需要的功能时用到的函数容器支不支持)

对与stack,只要容器支持 empty()、size()、back()、push_back()、pop_back() 这 5 个成员函数就可以作为stack第二个模板类型参数。

1. 创建stack对象 

 创建一个不包含任何参数的对象

stack<int> s1;   // 创建了一个存储int数据的stack对象, 如果我们不传入第二个类型参数,那么默认使用deque作为stack的 基础容器。

指定stack容器的基础容器 

我们可以通过类型参数的第二个参数指定stack的基础容器,但是只能使用vector,list,deque这三个容器中的一个。


stack<int,list<int>>  s1;   // 创建s1,我们指定了list容器作为stack容器的基础容器。

注意:  除去默认情况(使用deque容器为默认情况),我们要使用其它容器作为stack容器的基础容器,需要导入对应容器的头文件。

还有,虽然我们可以指定基础容器,但是默认的基础容器的效率是最高的。


比如:   使用list为基础容器,需要导入list头文件

#include <list> 

#inlcude <stack> 

stack<int,list<int>> s1; 

使用基础容器初始化stack容器。 

注意: 使用基础容器初始化stack容器,必须保证使用的基础容器和stack内部的基础容器是相同的。

deque<int> d1{ 1,2,3,4,5 };

// 使用别的容器初始化
stack<int> s1(d1);   // 使用deque容器的数据初始化stack,此时stack的基础容器应该为deque(也就是默认情况)。

vector<int> v1{ 1,2,3,4,5 };

// 使用别的容器初始化
stack<int,vector<int>> s1(v1);  // 使用vector容器的数据初始化stack,此时stack的容器英爱为vector。 

使用别的stack容器给stack初始化 

    vector<int> v1{ 1,2,3,4,5 };
    // 使用别的容器初始化
    stack<int,vector<int>> s1(v1);

    stack<int, vector<int>> s2(s1);   // 方式1:  使用s1初始化s2
    stack<int, vector<int>> s3 = s1; // 方式2:   使用s1初始化s3

2.  stack容器的函数

  • top()函数  --  无需参数

用于获取栈顶元素,函数内部其实是调用了基础容器的back()函数 -- 返回容器的最后的元素。  // 因为栈顶位置的元素是后进去的,对于基础容器而言就是容器最后的元素(可以通过back()函数获得)

  • push(elem)函数

用于压栈(就是往栈里面写数据),将数据压入栈中,函数内部其实是调用了基础容器的push_back()函数,将元素添加到基础容器的尾部。(因为栈是从栈顶元素添加数据,就相当于基础容器在尾部添加元素)

因为底层是push_back()所以其添加元素的形式,也是先拷贝数据,然后再将数据放到对应的位置上。

  • pop()函数  --  无需参数

用于出栈(就是从栈里面删除数据),函数内部其实是调用了基础容器的pop_back()函数,将元素从基础容器的尾部删除掉。(因为栈是从栈顶元素删除数据,就相当于基础容器在尾部删除元素)

  • 其余函数

其余函数和上面函数是一样的,都是通过调用内部基础容器的相应函数来实现功能,但是其用法和基础容器对应函数的用法是一样的,所以就不再说明了。

 

3. stack没有迭代器 

stack容器是没有迭代器的,我们使用迭代器的目的就是遍历容器中的数据,方便我们对当中的元素进行访问和操作,通过迭代器,可以访问到任意位置的元素。

但是stack是栈,其需求是只能从栈顶查询元素,只能从栈顶删除和插入元素, 可以看出栈我们只能从栈顶操作数据,我们使用相应的函数就可以实现,并不需要使用迭代器。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TAB标签美化 - SVG作为mask

今天觉得V3的标签不是很好看&#xff0c;忽然想起来之前看过Vue Admin Beautiful Pro的样式挺好的&#xff0c;顺手研究了一把。发现Vue Admin Beautiful是采用PNGmask css来解决的。于是乎打算把V3的标签页做点小美化&#xff0c;但是迁移过程发生些小插曲&#xff0c;在此记录…

第1讲——预备知识

一、视觉SLAM十四讲在讲些啥 SLAM&#xff1a;Simultaneous Localization and Mapping 翻译&#xff1a;同时定位与地图构建 搭载特定传感器的主体&#xff0c;在没有环境先验信息的情况下&#xff0c;于运动过程中建立环境的模型&#xff0c;同时估计自己的运动。 当特定传感…

Solidity入门1: 3. 函数类型

Solidity中的函数 solidity官方文档里把函数归到数值类型 函数结构 function <function name>(<parameter types>) {internal|external|public|private} [pure|view|payable] [returns (<return types>)] 看着些复杂&#xff0c;咱们从前往后一个一个看&…

【MySQL】:深入解析多表查询(上)

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; MySQL从入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. 多表关系1.1 一对多1.2 多对多1.3 一对一 二. 多表查询概述2.1 概述2.2 分类…

Docker Desktop 不支持 host 网络模式

先把这个结论的放在前面&#xff0c;直接访问链接就能看到官方文档中已经明确说了不支持。 参考链接&#xff1a;docker desktop for windows 不支持 host 网络模式 以前对于 docker 的网络模式&#xff0c;一直只是了解&#xff0c;没有亲自尝试过。结果今天在尝试 docker 的 …

『大模型笔记』LLMs入门:从头理解与编码LLM的自注意力机制

LLMs入门&#xff1a;从头理解与编码LLM的自注意力机制 这里直接引用我语雀上的的文章&#xff1a;《从头理解与编码LLM的自注意力机制》

科东软件参加广州机器人产业联盟举办先进工业母机专家研讨会

工业母机是“制造机器的机器”&#xff0c;具有基础性、通用性、战略性特征&#xff0c;包括了减材切削机床、等材成形装备、增材制造装备及其控制系统等&#xff0c;是衡量国家工业水平和竞争力的重要标志。广东省作为全球知名的制造业基地&#xff0c;非常重视高端装备领域工…

python 笔记

文章目录 pdbpdb开始调试pythonpdb设置断点单步执行进入到函数的内部执行到下一个断点或程序结束调用栈查看命令查看当前函数调用堆栈向上一层函数查看调用堆栈查看源代码 importimport 用法 numpy导入numpy模块numpy常用函数np.argmaxnp.sum range生成连续序列生成不连续序列 …

【随笔】Git 高级篇 -- 撤销变更(十四)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

如何使用 Midjourney?2024年最新更新

一&#xff1a;基础篇 1&#xff1a;注册 首先&#xff0c;你需要注册一个 Discord 账号&#xff0c;然后加入 Midjourney 的 Discord 服务器。或者去 Midjourney 的官网点击右下角的 Join the Beta&#xff1a; ​ 2&#xff1a;在 Discord 公共服务器里使用 注册并进入到…

一、Docker部署GitLab(详细步骤)

Docker部署GitLab&#xff08;详细步骤&#xff09; 一、拉取镜像二、启动容器三、修改配置四、修改密码五、浏览器访问 一、拉取镜像 docker安装教程&#xff1a;https://qingsi.blog.csdn.net/article/details/131270071 docker pull gitlab/gitlab-ce:latest二、启动容器 …

MySQL数据库 数据库基本操作(三):表的增删查改(中)

1. 数据库的约束 1.1 约束类型(一般发生于表的创建中) NOT NULL - 指示某列不能存储 NULL 值。UNIQUE - 保证某列的每行必须有唯一的值。DEFAULT - 规定没有给列赋值时的默认值。PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列&#xff08;或两个列多个列的结合&#xf…

一站式自动化测试平台-Autotestplat

3.1 自动化平台开发方案 3.1.1 功能需求 3.1.3 开发时间计划 如果是刚入门、但有一点代码基础的测试人员&#xff0c;大概 3 个月能做出演示版(Demo)进行自动化测试&#xff0c;6 个月内胜任开展工作中项目的自动化测试。 如果是有自动化测试基础的测试人员&#xff0c;大概 …

突破!AI机器人拥有嗅觉!仿生嗅觉芯片研究登上Nature子刊

我们一直梦想着让AI与人类能够更加相似&#xff0c;赋予它们视觉与听觉。而让机器人拥有嗅觉一直以来面临着巨大的困难。 香港科技大学范志勇教授领导的研究团队凭借最新研发的仿生嗅觉芯片&#xff08;BOC&#xff09;在这一领域取得了重大突破。该研究成果目前已被发表到IF …

代码随想录算法训练营DAY17|C++二叉树Part.4|110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和

文章目录 110.平衡二叉树思路伪代码CPP代码 257.二叉树的所有路径思路伪代码实现CPP代码 404.左叶子之和思路伪代码CPP代码 110.平衡二叉树 力扣题目链接 文章讲解&#xff1a;110.平衡二叉树 视频讲解&#xff1a;后序遍历求高度&#xff0c;高度判断是否平衡 | LeetCode&…

COCO格式转YOLO格式训练

之前就转换过好几次&#xff0c;每次换设备训练&#xff0c;由于压缩包太大&#xff0c;u盘不够用。每次都要找教程从网上再下载一遍。因此这里记录一下&#xff0c;以免下次重新找教程。 在coco数据集中&#xff0c;coco2017train或coco2017val数据集中标注的目标(类别)位置在…

Qt事件学习案例

视频链接 https://www.bilibili.com/video/BV18B4y1K7Cs?p7&spm_id_frompageDriver&vd_sourcefa4ef8f26ae084f9b5f70a5f87e9e41bQt5跟着视频做即可&#xff0c;Qt6部分代码需要改动,改动的地方注释有写 素材 百度云 链接&#xff1a;https://pan.baidu.com/s/158j…

金三银四面试题(十四):Java基础问题(5)

这部分面试题多用于面试的热身运动&#xff0c;对很多找实习和准备毕业找工作的小伙伴至关重要。 避免序列化 可以使用transient 关键字修饰不想进行序列化的变量。 transient 关键字的作用是&#xff1a;阻止实例中那些用此关键字修饰的变量序列化&#xff1b;当对象被反序列…

Python 网络请求:深入理解Requests库

目录 引言 一、Requests库简介 二、安装与基本使用 三、requests库的特性与优势 四、requests库在实际应用中的案例 1.get请求 2.post请求 3.超时重试 4.headers设置 5.session会话 6.携带cookie​​​​​​​ 7.携带代理​​​​​​​ 8.携带身份认证​​​​​…

Windows集群部署项目

目录 一&#xff0c;环境准备 1.1.安装MySQL 1.2.安装JDK 1.3.安装TomCat 1.4.安装Nginx 二&#xff0c;部署 2.1.后台服务部署 2.2.Nginx配置负载均衡及静态资源部署 一&#xff0c;环境准备 1.1.安装MySQL 可以参考博客&#xff1a;http://t.csdnimg.cn/A75bg 1.2.…