【C++】STL——stack和queue

news2024/10/10 14:34:31

目录

  • 前言
  • 容器配接器(适配器)
  • stack的使用
  • stack的模拟实现
  • queue的使用
  • queue的模拟实现
  • 双端队列(deque)

请添加图片描述

前言

前面我们已经学习了STL容器中的string、vector还有list。

【C++】string的模拟实现
【C++】STL——vector的模拟实现
【C++】STL——list的模拟实现

下面我们来学习stack和queue。
在这里插入图片描述
  但是我们由STL这张图可以看出,stcak和queue并不在容器中,而是在配接器中。什么是配接器,下面来讲解一下。

容器配接器(适配器)

  什么是适配器适配器是一种设计模式设计模式是一套被反复使用的,多人知晓的,经过分类编目的,代码设计经验的总结),该种模式是将一个类的接口转换为客户希望的另外一个接口。

具体了解可看:百度百科——适配器

在这里插入图片描述
  所以实际上,适配器的本质就是转换,把原始接口转换为客户想要的就行。
  stack和queue中也可以存放元素,但STL中并没有将其放在容器中,而是将其称为容器适配器,是因为stackqueue只是对其他容器的接口进行了包装,而这个其他容器,在STL中默认使用的是deque(双端队列,后面会稍微讲解一下).
库里面对stack和queue的定义如下:
在这里插入图片描述
在这里插入图片描述

  可以看出,stack和queue都使用了deque,将其进行了包装,就转换成了栈和队列。

stack的使用

  stack是一种容器适配器,专门设计用于在 LIFO (后进先出)上下文中运行,其中元素仅从容器的一端插入和提取。

  stack的底层容器可以是任何标准的容器类模板或者其他一些特定的容器类,这些容器应支持以下操作:

  • empty:判空操作
  • back:获取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部删除元素操作

  标准容器vector、deque、list均符合这些要求,默认情况下,如果没有为stack指定特定底层容器,默认使用deque(双端队列)。
stack的使用接口并不多,就如下几个:

函数说明接口说明
stack()构造空的栈
empty()检测栈是否为空
size()返回栈中元素个数
top()返回栈顶元素的引用
push()将元素val压入栈中
pop()将stack中尾部元素弹出

一个简单的使用样例给到大家参考:

#include<iostream>
#include<list>
#include<deque>
#include<stack>
using namespace std;

int main()
{
	stack<int> s;//不写底层容器默认给deque
	stack<int, list<int>> sl;
	stack<int, deque<int>> sd;
	//使用typeid可以查看类型
	cout << typeid(s).name() << endl;
	cout << typeid(sl).name() << endl;
	cout << typeid(sd).name() << endl;

	s.push(1);
	s.push(2);
	s.push(3);

	cout << "s.size():" << s.size() << endl;
	cout << "s中的元素有:";
	while (!s.empty())
	{
		cout << s.top() << " ";
		s.pop();
	}

	return 0;
}

结果如下:
在这里插入图片描述

stack的模拟实现

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

模拟实现也比较简单:

namespace bit
{
	template<class T,class Container = deque<T>>
	class stack
	{
		//默认成员函数都不用自己去写,用底层容器默认生成的即可
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		T& top()
		{
			return _con.back();
		}
		const T& top() const
		{
			return _con.back();
		}
		size_t size() const
		{
			return _con.size();
		}
		bool empty() const
		{
			return _con.empty();
		}
	private:
		Container _con;
	};

  我们发现,stack私有成员变量就是一个底层容器,而stack类的所有默认成员函数都不用自己写,都直接调用底层容器的默认成员函数即可,包括其他函数的实现,我不需要去管,因为底层容器已经实现好了,我们只需调用即可,这就是容器适配器的好用之处。

queue的使用

  队列也是一种容器适配器,专门用于在FIFO(先进先出)上下文中操作,其中从容器一端插入元素,另一端提取元素。
  队列作为容器适配器实现,容器适配器将特定容器类封装作为其底层容器类,底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

  • empty:判空操作
  • size:获取队列中有效元素个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部如队列
  • pop_back:在队列头部出队列

  标准容器类deque和list满足了这些需求,默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

list的使用和stack完全一致,接口也就这几个:

函数说明接口说明
queue()构造空的队列
empty()检测队列是否为空
size()返回队列中元素个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()将元素val压入栈中
pop()将队头元素出队列

使用样例如下:

#include<iostream>
#include<list>
#include<deque>
#include<queue>

using namespace std;

int main()
{
	queue<int> q;//不写底层容器默认给deque
	queue<int, list<int>> ql;
	queue<int, deque<int>> qd;
	//使用typeid可以查看类型
	cout << typeid(q).name() << endl;
	cout << typeid(ql).name() << endl;
	cout << typeid(qd).name() << endl;

	q.push(1);
	q.push(2);
	q.push(3);

	cout << "s.size():" << q.size() << endl;
	cout << "队尾元素:" << q.back() << endl;
	cout << "s中的元素有:";
	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}

	return 0;
}

queue的模拟实现

queue的模拟实现和stack类似,同样通过模板和底层容器deque来实现:

namespace bit
{
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		bool empty() const
		{
			return _con.empty();
		}
		size_t size() const
		{
			return _con.size();
		}
		T& front()
		{
			return _con.front();
		}
		const T& front() const
		{
			return _con.front();
		}
		T& back()
		{
			return _con.back();
		}
		const T& back()
		{
			return _con.back();
		}
		void pop()
		{
			return _con.pop_front();
		}
		void push()
		{
			return _con.push_back;
		}
	private:
		Container _con;
	};
}

要注意函数之间的调用:

  1. queue中的pop函数要调用deque的pop_front删除第一个元素的函数
  2. queue中的push函数要调用deque的push_back尾插函数

双端队列(deque)

通过几张图来简单瞧一瞧双端队列:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  对于双端队列中间的各种操作我们不再细说,我们直接来说一说deque的优点和缺陷
优点

  • 与vector比较头插头删不需要搬移元素效率较高,扩容也不需要搬移大量元素。
  • 与List比较,底层是连续的空间,空间利用率高

缺陷:不适合遍历。

所以选择deque作为stack和queue的底层默认容器主要原因为

  1. stack和queue不需要遍历
  2. stack元素增长时,deque比vector的效率高(不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。
    结合了deque的优点,且完美避开了缺点。

感谢大家观看,如果大家喜欢,希望大家一键三连支持一下,如有表述不正确,也欢迎大家批评指正。
请添加图片描述

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

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

相关文章

gradle降级

文章目录 引子编译错误参考 引子 项目引入了一个高版本项目改造&#xff0c;编译运行失败&#xff0c;提示如下错误&#xff0c;解决方案要么升级gradle版本&#xff0c;升级适配改各种方法配置&#xff0c;现有的项目存在适配问题&#xff1b;要么就是版本降级。 本文以介绍…

docker环境redis启动失败

现象&#xff1a; 查看日志错误为 Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename> 经查询为aof文件损坏导致&#xff0c;修复aof即可 解决方法&#xff1a; 1.查看执行的docker命令&…

c到c++衔接速成

温馨提示&#xff1a;本篇文章乃博主多次学习后的总结&#xff0c;其中一些专业名词的概念不会做介绍&#xff0c;本篇文章只解决实操问题 c到c中&#xff0c;语法上得到了许多升级&#xff0c;那么哪些地方升级了&#xff0c;我们来快速复习一下 目录 头文件的升级 命名空间…

国产长芯微LDC5791是一款单通道、20位、无缓冲电压输出DAC完全P2P替代AD5791

描述 LDC5791是一款单通道、20位、无缓冲电压输出DAC&#xff0c;采用最高33 V的双极性电源供电。正基准电压输入范围为5 V至VDD – 2.5V&#xff0c;负基准电压输入范围为VSS 2.5 V至0 V。相对精度最大值为1 LSB&#xff0c;保证工作单调性&#xff0c;差分非线性(DNL)最大值…

基于echarts的旅游信息(游客行为分析)大数据可视化平台(echarts+Django+MySQL+Scrapy框架爬虫;程序+论文+开题报告)

摘要 本论文旨在研究Python技术和ECharts可视化技术在游客行为分析系统中的应用&#xff0c;通过对旅游数据的深入分析&#xff0c;希望能够揭示出南京旅游市场的现状和趋势&#xff0c;从而为游客提供更优质的旅游体验&#xff0c;也可以为政府和旅游企业制定更加科学和有效的…

Spring事务的1道面试题

每次聊起Spring事务&#xff0c;好像很熟悉&#xff0c;又好像很陌生。本篇通过一道面试题和一些实践&#xff0c;来拆解几个Spring事务的常见坑点。 原理 Spring事务的原理是&#xff1a;通过AOP切面的方式实现的&#xff0c;也就是通过代理模式去实现事务增强。 具体过程是…

2024年诺贝尔物理学奖

2024年&#xff0c;诺贝尔物理学奖没有颁给物理学家&#xff0c;而是授予了两位计算机科学家&#xff0c;表彰他们在神经网络领域的开创性工作&#xff0c;这项研究成为了我们今天所称的人工智能的基础。这标志着物理学与计算机科学之间的深度融合。 获奖者约翰霍普菲尔德和杰弗…

财政警钟敲响!CBO预测:美国2024财年赤字预计达1.8万亿美元

KlipC报道&#xff1a;美国国会预算办公室&#xff08;CBO&#xff09;近日发布报告显示&#xff0c;2024财年&#xff08;2023年10月1日至2024年9月30日&#xff09;&#xff0c;美国联邦政府预算赤字高达1.8万亿美元&#xff0c;与上一财年相比增加了1390亿美元。据CBO预测&a…

转型AI产品经理需要掌握的硬知识、经理能力模型和常见AI概念梳理

近几年&#xff0c;从亚马逊&#xff0c; Facebook&#xff0c;到谷歌&#xff0c;微软&#xff0c;再到国内的BAT&#xff0c;全球最具影响力的技术公司都将目光转向了人工智能&#xff08; AI &#xff09;。2016年 AlphaGo 战胜李世石&#xff0c;把公众的目光也聚集到了人工…

IROS24新鲜出炉:PRL-Track,最先进的无人机视觉目标跟踪系统!

导读&#xff1a; 近年来&#xff0c;随着无人机技术的飞速发展&#xff0c;视觉目标跟踪在无人机的自主应用中扮演着越来越重要的角色&#xff0c;然而&#xff0c;在复杂多变的环境中&#xff0c;实现高精度的目标跟踪并非易事。无人机在飞行过程中&#xff0c;常常会遇到目标…

介绍几个电池充电管理芯片(TP4056、SGM40561)

TP4056 上一篇我们介绍了个TP4055&#xff0c;那么跟TP4055相比&#xff0c;TP4056肯定是做了升级的。 首先是有最高1000mA的充电电流&#xff0c;而TP4055是500mA。 一般来说我们尽可能的让充电电流接近电池容量的一半&#xff0c;这样对电池比较好。 充电电压都是4.2V。 …

winform实现托盘语音提醒

测试环境: visual studio 2022 window 10 .net framework 4.6 本文实现的功能有&#xff1a; 1 托盘最小化 2 语音定时播放 3 检测到操作系统被客户点静音后&#xff0c;需要程序控制开启音量(在运行过程中&#xff0c;由于语音重复播放&#xff0c;客户很烦&#…

【Protobuf】基本使用总结+项目实践

概述 序列化与反序列化 网络传输中使用&#xff0c;可以实现将对象转换为二进制序列&#xff0c;然后将二进制序列转换为对象&#xff0c;这一个交互的过程就是序列化。生成的数据&#xff0c;持久化存储到磁盘上的过程&#xff0c;也需要经过序列化和反序列化才可以实现。 序…

SpringBoot实现的美发门店客户关系管理(CRM)系统

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

浅谈2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者

目录 1.概述 1.1. 跨学科的融合 1.2. 推动科学研究的工具 1.3. 对科学界的激励 1.4. 技术的社会影响 2.机器学习与神经网络的发展前景 2.1.具体应用与作用 2.1.1. 医疗健康 2.1.2. 金融 2.1.3. 制造业 2.1.4. 交通与物流 2.1.5. 零售 2.2.未来展望 2.3.科学研究与…

C# 实现调用函数,打印日志(通过反射代理、非IOC)

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C# &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff…

宝塔面板配置FTP服务结合内网穿透实现其他设备远程连接上传文件

文章目录 前言1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结 5. 固定FTP公网地址6. 固定FTP地址连接 前言 本文主要介绍宝塔FTP文件传输服务如何搭配内网穿透工具&#xff0c;实现随时随地远程连接局域网环境搭建的宝塔FTP文件服务并进行文件…

电商数据淘宝/京东/1688商品SKU数据采集||电商API接口

电商数据采集接口数据分析是一个涉及多个步骤的过程&#xff0c;以下是一个详细的指南&#xff1a; 一、数据采集接口的选择与接入 选择合适的电商数据采集接口&#xff1a; 根据需求选择提供所需数据的电商平台接口。考虑接口的稳定性、数据更新频率及准确性。 接口接入准备&…

《网络数据安全管理条例》正式公布,规范数据处理活动,保障网络数据安全

近日&#xff0c;《网络数据安全管理条例》&#xff08;以下简称《条例》&#xff09;正式公布&#xff0c;自2025年1月1日起施行。 《条例》旨在规范网络数据处理活动&#xff0c;保障网络数据安全&#xff0c;促进网络数据依法合理有效利用&#xff0c;保护个人、组织的合法权…

java时间复杂度与空间复杂度的排序

怎么理解时间复杂度和空间复杂度 时间复杂度和空间复杂度一般是针对算法而言&#xff0c;是衡量一个算法是否高效的重要标准。先纠正一个误区&#xff0c;时间复杂度并不是算法执行的时间&#xff0c;再纠正一个误区&#xff0c;算法不单单指冒泡排序之类的&#xff0c;一个循…