【STL】容器适配器stack和queue常见用法及模拟实现

news2024/11/20 4:44:48

目录

      • 1.stack介绍及使用
        • 1.1 stack的介绍
        • 1.2 stack使用
      • 2. stack模拟实现
      • 3. queue介绍及使用
        • 3.1 queue的介绍
        • 4. queue模拟实现
      • 5. 栈和队列使用不同默认适配器的区别
      • 6. dequeue原理简单介绍
        • 6.1 dequeue底层实现
        • 6.2 dequeue的缺点

1.stack介绍及使用

1.1 stack的介绍

stack文档介绍
在这里插入图片描述

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
  2. stack是作为容器适配器被实现的,容器适配器是使用特定容器类的封装对象作为其基础容器的类,提供一组特定的成员函数来访问其元素。元素从特定容器的“背面”(称为堆栈顶部)推/弹出。
  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下
    操作:
    empty:判空操作
    back:获取尾部元素操作
    push_back:尾部插入元素操作
    pop_back:尾部删除元素操作
  4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。

这里的stack也就是我们数据结构中学习的栈:
在这里插入图片描述

接下来我们看一下它的成员函数:
在这里插入图片描述
这些成员函数基本都是我们熟悉的。注意:stack是没有迭代器的,stack要保证先进后出,所以其实它不需要迭代器。

1.2 stack使用
#include <iostream>
using namespace std;
#include <stack>

int main()
{
	stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	st.push(4);
	st.push(5);
	st.push(6);
	while (!st.empty())
	{
		cout << st.top() << " ";
		st.pop();
	}
	cout << endl;
	return 0;
}

我们来测试一下:
在这里插入图片描述

2. stack模拟实现

这里我们在模拟实现的时候使用容器适配器。简单的理解容器适配器,其就是将不适用的序列式容器(包括 vector、deque 和 list)变得适用。即通过封装某个序列式容器,并重新组合该容器中包含的成员函数,使其满足某些特定场景的需要。

#include <iostream>
#include <vector>
#include <deque>
#include <stack>

namespace w
{
    template <class T, class Container = std::vector<T>>
    class stack
    {
    public:

        void push(const T& x)
        {
            _con.push_back(x);
        }

        void pop()
        {
            _con.pop_back();
        }

        T& top()
        {
            return _con.back();
        }

        bool empty()
        {
            return size() == 0;
        }

        size_t size()
        {
            return _con.size();
        }

    private:
        Container _con;
    };
}

注意:我们在模板上面添加对应栈结构的适配容器来支持栈的添加、删除、获取元素的操作。并且我们将它设置为缺省参数,我们传参时就可以不传适配器,它就会使用自己默认的适配容器.

3. queue介绍及使用

3.1 queue的介绍

queue文档介绍

  1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端
    提取元素。
  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的
    成员函数来访问其元素。元素从队尾入队列,从队头出队列。
  3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操
    作:
    empty:检测队列是否为空
    size:返回队列中有效元素的个数
    front:返回队头元素的引用
    back:返回队尾元素的引用
    push_back:在队列尾部入队列
    pop_front:在队列头部出队列
  4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。
    在这里插入图片描述

那么对于队列我想也不用过多和大家介绍了。

4. queue模拟实现
#include <iostream>
#include <list>
#include <deque>
#include <queue> 
namespace w
{
    template <class T, class Container = std::list<T>>
    class queue
    {
    public:

        void push(const T& x)
        {
            _con.push_back(x);
        }

        void pop()
        {
            _con.pop_front();
        }

        T& front()
        {
            return _con.front();
        }

        bool empty()
        {
            return size() == 0;
        }

        size_t size()
        {
            return _con.size();
        }

    private:
        Container _con;
    };
}

5. 栈和队列使用不同默认适配器的区别

栈使用的适配器:
在这里插入图片描述
队列使用的适配器:
在这里插入图片描述

1.栈使用vector作为适配器可以减少一直开辟空间的消耗,提高效率
2.队列使用list而不使用vertor,是因为vector不适用区头删元素,这是由于队列的特性导致vertor不适用
3 . 为此,STL标准库为了让栈和队列使用统一的适配器,又产生了一个新的适配器,也就是(dequeue)双端队列,这个容器适合给栈和队列当作默认适配器

6. dequeue原理简单介绍

6.1 dequeue底层实现

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和 删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
在这里插入图片描述

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示
在这里插入图片描述
双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:
在这里插入图片描述

那dequeue是如何借助迭代器进行工作的呢?
使用cur进行++遍历,cur不等于last就一直进行++操作,当等于last后,node指向下个buffer,map存的是指针数组的映射,那么first和last也指向下一个的buffer的开头和结尾,cur指向first的位置,,往复如此,到最后一个buffer的时候,cur等于end()就遍历结束。

6.2 dequeue的缺点
  1. 与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。
  2. 与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。
  3. 但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

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

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

相关文章

每天debug/run一键启动的Spring Boot控制台启动日志,你了解过吗?

文章目录 前言JDK执行Spring Boot应用的启动命令Spring Boot本身启动时的日志总结 前言 每次打开Idea点击debug/run启动SpringBoot项目时&#xff0c;都在坐等启动成功的最后一行日志&#xff0c;然而对于启动过程中&#xff0c;控制台里面的每一行日志代表什么&#xff1f;你…

论文学习——FALL-E:GAUDIO FOLEY SYNTHESIS SYSTEM

文章目录 引言正文AbstractIntroduction介绍问题 FALL-E2.1 Architexture结构2.2 Training and Inference Details 3 Evaluation And Analysis测试和分析Conlusion 总结 引言 这篇文章是DCASE中少有的&#xff0c;没有使用DIffusion的方法&#xff0c;可以学习一下。这篇文章的…

『C++之STL』双端队列 - deque

前言 双端队列,Double-ended queue,简称为deque是一种线性结构的一种容器; 在数据结构中出现的顺序表与链表,或者栈与队列都算是线性结构; 在结构中,它与vector相比较会相似一些; 但是在实际当中,双端队列 - deque 包含了vector与list的优点; vector(顺序表) 支持随机访问,空…

cuda12+vs2019环境搭建 发疯实录

点击exe文件后开始安装&#xff08;注意更改默认安装的位置&#xff09; 在选项阶段&#xff0c;全选所有的选项 出现的问题&#xff0c;这里显示未安装 进一步地查看原因 可能式对应的版本下载错误 如何寻找到所需要的版本并进行下载&#xff1f; 在上述参考链接中进行搜…

阿里云韩国服务器测试IP地址及公网带宽收费价格表

阿里云服务器韩国&#xff08;首尔&#xff09;地域公网带宽价格表&#xff0c;1M带宽价格是23.0元/月&#xff0c;按使用流量1GB价格是0.8元&#xff0c;阿里云韩国服务器测试IP地址&#xff1a;149.129.12.20&#xff0c;阿里云百科aliyunbaike.com来详细说下阿里云韩国服务器…

mybatis用拦截器实现字段加解密

前言 根据公司业务需要&#xff0c;灵活对客户敏感信息进行加解密&#xff0c;这里采用mybatis拦截器进行简单实现个demo。 拦截器的使用 // 执行 Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) // 请求参数处理 Paramete…

基于蛾群优化的BP神经网络(分类应用) - 附代码

基于蛾群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于蛾群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.蛾群优化BP神经网络3.1 BP神经网络参数设置3.2 蛾群算法应用 4.测试结果&#xff1a;5.M…

常用的数字格式代码

文章目录 数值占位符文本占位符 两类占位符: 数值占位符, 文本占位符. 数值占位符 有三种&#xff1a;0&#xff0c;#&#xff0c;&#xff1f; 0 是强制的占位符。 文本占位符 文本占位符只有一个&#xff1a; : 作用于文本的占位符&#xff0c;可以用英文引号" &quo…

DirectX绘制流水线

使用DirectX可以让在Windows平台上运行的游戏或多媒体程序获得更高的执行效率&#xff0c;掌握DirectX的基本概念和技术是虚拟现实技术、计算机仿真和3D游戏程序开发的基础。 DirectX概述 DirectX是微软的一个多媒体应用编程接口(API)工具包&#xff0c;用于为Windows操作系统…

Qt QMovie和QLabel配合播放GIF表情包

文章目录 效果演示main函数创建MoviePlayer对象头文件movieplayer.h源文件movieplayer.cpp代码解释在Qt框架中,QMovie是用于处理动画和视频的类。所有源码已在本篇文章公布。 效果演示 main函数创建MoviePlayer对象 #include <QApplication>#include "movie

JAVAEE初阶相关内容第十三弹--文件操作 IO

写在前 终于完成了&#xff01;&#xff01;&#xff01;&#xff01;内容不多就是本人太拖拉&#xff01; 这里主要介绍文件input&#xff0c;output操作。File类&#xff0c;流对象&#xff08;分为字节流、字符流&#xff09; 需要掌握每个流对象的使用方式&#xff1a;打…

MySQL jdbc,事务,连接池

​​​ 3-MySQL jdbc,事务,连接 1 jdbc 1.1 jdbc概述# JDBC&#xff08;Java DataBase Connectivity,java数据库连接技术&#xff09;是一种用于执行SQL语句的Java API。 JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c;它由一…

php对接微信支付简要流程?面试时你会描述吗?

一、微信支付申请&#xff1a;微信公众号平台-->功能中找到微信支付-->申请接入 1.如果没有微信支付商会号&#xff0c;需要进行申请 提交营业执照、身份证、银行账户 2.如果有微信支付商会号 可进行直接关联 登录微信商户平台—产品中心—APPID授权管理—新增授权申…

视频编辑软件 Premiere Pro 2024 macv24.0中文版 (pr2024)

Premiere Pro 2024 mac编辑任何现代格式的素材&#xff0c;从8K到虚拟现实。广泛的原生文件支持和简单的代理工作流程可以轻松使用您的媒体&#xff0c;即使在移动工作站上也是如此。提供针对任何屏幕或平台优化的内容比以往任何时候都快。 Premiere Pro 2024 Mac版软件介绍 视…

深度强化学习 第 2 章 蒙特卡洛

2.1随机变量 强化学习中会经常用到两个概念&#xff1a; 随机变量、 观测值。 本书用大写字母表示随机变量&#xff0c;小写字母表示观测值&#xff0c;避免造成混淆。 下面我们定义概率质量函数&#xff08;probability mass function&#xff0c;缩写 PMF&#xff09;和概率…

SpringBoot面试题5:SpringBoot Starter的工作原理是什么?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot Starter的工作原理是什么? Spring Boot Starter 是一种便捷的方式来为 Spring Boot 应用程序引入一组特定功能的依赖项。它简化了项目…

【Java并发】聊聊LongAdder应用场景及其原理

应用场景 我们知道在实际的应用场景中&#xff0c;可能会对某个商品进行浏览次数进行迭代&#xff0c;或者抖音视频的点击&#xff0c;那么如何高效记录呢&#xff0c;首先如果是使用普通的num 进行多线程操作的话&#xff0c;那么一定会带来数据一致性问题&#xff0c;所以一…

【Unity基础】6.动画状态机

【Unity基础】6.动画状态机 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;Animator Controller组件 &#xff08;1&#xff09;创建组件 Animator Controller组件是unity用于控制管…

【细读经典】delay model and timing analysis

Technology-Dependent LogicOptimization, part 1 序言 如图所示是现代工业流程中对于一个高层次的抽象描述如何到最后的芯片的流程图&#xff0c;其中逻辑综合作为一个非常重要的部分&#xff0c;主要被分为两个阶段&#xff1a; 工艺无关的优化(technology-independent opt…

shell脚本学习笔记03(小滴课堂)

在shell脚本中&#xff0c;表示变量除了可以使用$a(a是一个变量)&#xff0c;还可以使用${a} 那这两种表示方式有什么区别么&#xff1f; 花括号可以和其它字符或者字母区分开来。 >追加内容 我们发现使用>会把原来的内容覆盖。 我们使用>>就不会覆盖了&#xff…