【STL】stack、queue基本使用和模拟实现

news2024/11/16 19:40:16

目录

前言

stack

接口介绍

模拟实现

queue

接口介绍

模拟实现

没有迭代器 

deque介绍


前言

stack 和 queue 本质上是一种容器配接器,就像我们平时充电时使用的电源适配器,能够将电压转换成设备能够接受的程度。

其通过封装特定容器作为其底层容器的类,通过一组特定的成员函数来实现结构的功能。


stack

🍑stack 就是 STL 中封装好的栈,在使用的时候我们不仅可以指定内部的数据类型,还可以指定内部的容器

🍑不指定容器其实也是可以的,内部的模板参数有一个缺省值

int main()
{
	stack<int, vector<int>> s1;     //内部容器为vector
	stack<int, list<int>> s2;       //内部容器为list
    stack<int> s3;                  //内部为默认容器deque
	return 0;
}

接口介绍

🍑库中还提供了一系列的接口,我们以前如何使用栈就如何使用 stack 即可,下面用一系列代码来示例一下。 

int main()
{
	stack<int> s;
	s.push(5);          //5
	s.push(6);          //5 6
	s.push(7);          //5 6 7
	s.push(8);          //5 6 7 8
	cout << s.size() << endl;   //打印栈的大小
	while (!s.empty())        //直到栈为空循环
	{
		cout << s.top() << endl;   //打印栈顶元素
		s.pop();                   //出栈
	}
	return 0;
}

 

模拟实现

🍑根据库中接口简单地实现一下 stack,需要注意的是这里复用的接口需要确保几个底部容器都要同时拥有

namespace Alpaca
{
	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

🍑queue 则是封装出来的队列,与 stack 相反遵循着先进先出的原则(FIFO)。

🍑通过查询资料我们还发现,要作为 queue 的容器还需要支持以下操作:

🍑同样,使用 queue 时模板参数有两个,分别是内部元素的类型和内部容器,且内部容器缺省为 deque。

int main()
{
	queue<int> q1;                //传递缺省模板参数
	queue<int, list<int>> q2;     //指定内部容器为list
	return 0;
}

接口介绍

🍑队列与栈相反,其只在队尾入队,在队头出队。我们可以通过实例代码简单使用一下。

int main()
{
	queue<int> q;
	cout << "size is: " << q.size() << endl;   //查看队列大小
	q.push(1);                                 //数据入队
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);
	cout << "size is: " << q.size() << endl;   
	cout << "first is: " << q.front() << endl; //查看首元素
	cout << "last is: " << q.back() << endl;   //查看最后一个元素
	while (!q.empty())                         //直到队空循环
	{
		cout << q.front() << " ";              //打印队头
		q.pop();                               //出队
	}
	cout << endl;
	cout << "size is: " << q.size() << endl;   //查看队列大小
	return 0;
}

模拟实现

🍑由于是泛型在使用的时候并不会对内部函数进行提示,简单理解就是我们复用对应容器的接口来实现队列的接口函数

namespace Alpaca
{
	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;
	};

}

没有迭代器 

🍑因为无论是 stack 和 queue 都是根据其特定的顺序进行元素的插入和删除,因此二者都不提供走访功能,也不提供迭代器。

deque介绍

🍑在出现 vector 和 list 之后,有人想到 vector 能够随机读取,但扩容和随机插入删除效率较低,而 list 插入删除效率都极高却无法随机访问,能不能实现一个结构能够同时兼顾 vector 和 list 的优点呢?

🍑于是 deque 就诞生了,deque 又叫双端队列,即一种双向开口的连续线性空间

🍑为了兼顾双端插入以及随机访问,deque 的底层是使用一个中控数组来管理一个个连续的空间,且第一个空间被开辟出来后是存放在中控数组的中央位置,之后不断插入数据,若一块连续空间已满只需要再开一块连续空间即可。也就是在中控数组中再增加一个指针。

🍑若是进行头插,则需要开辟一段新空间,将新的值存于连续空间的尾部

🍑得益于这种结构,即便是扩容所带来的拷贝消耗也是极低的,实际上不会像 vector 那样复杂的深拷贝,而只是对中控数组中的指针进行拷贝。同时  deque 也支持随机访问,只要直到每个连续空间的大小通过简单的计算便可以实现随机访问。

🍑若 deque 有这么多的有点,那为什么它还没有取代 vector 和 list 呢?这就不得不提到 deque 最为鸡肋的地方了,中部的插入删除操作相当复杂,若是直接在中部插入就要挪动当前空间的数据,更甚者还要牵扯到接下来的连续空间。不仅如此 deque 提供的优点不如 vector 和 list 那样极致,这也是为什么 deque 代替不了二者的原因。

🍑但若是有一种容器并不需要中间的插入删除,只需要在两端进行插入删除呢?于是 deque 就成为了适合 stack 和 queue 实现的内部容器


🍑好了,今天 stack、queue基本使用和模拟实现 的相关内容到这里就结束了,如果这篇文章对你有用的话还请留下你的三连加关注。

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

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

相关文章

我的测试之路:从入坑测试到月薪15k...

“干过保险卖过房&#xff0c;做过销售做过网管”这是我毕业后前两年的真实写照&#xff0c;因为所学网络安全专业不好找工作&#xff0c;毕业之后为了生活只能将就的干着这种门槛低的工作。后来一次同学聚会被同学带下坑后&#xff0c;正式转行软件测试。 刚入坑的两年&#…

【自动化测试实战】从 0 到 1 搭建 Dubbo 接口自动化测试

前言 1、Dubbo 接口自动化测试框架实现逻辑 2、框架具体功能 3、关键实践 3.1 下载 provider 的 jar 包&#xff0c;并代理声明 zookeeper 设置 3.2 邮件发送功能 3.3 封装 Dubbo 接口信息类 3.4 利用 JMeter 调用 provider 服务&#xff0c;并断言&#xff0c;邮件报警…

音视频基础及海思sample_venc解读

1、sample的整体架构 (1)sample其实是很多个例程&#xff0c;所以有很多个main (2)每一个例程面向一个典型应用&#xff0c;common是通用性主体函数&#xff0c;我们只分析venc (3)基本的架构是&#xff1a;venc中的main调用venc中的功能函数&#xff0c;再调用common中的功…

python基于DeeplabV3Plus开发构建裂缝分割识别系统,并实现裂缝宽度计算测量

在我之前的文章中已经有不少基于裂缝场景的数据开发构建的模型了&#xff0c;感兴趣的话可以自行移步阅读&#xff0c;如下&#xff1a; 《基于yolov5sbifpn实践隧道裂缝裂痕检测》 《基于YOLOV7的桥梁基建裂缝检测》 《水泥路面、桥梁基建、隧道裂痕裂缝检测数据集》 《基…

SpringBoot异步执行方法

1. 源码跟踪 1.简单描述 在SpringBoot2.0.9之前需要手动自定义线程池(如下2.1), 然后指定线程池的名称 SpringBoot2.0.9以及之前的版本,使用的线程池默认是SimpleAsyncTaskExcutor, , 之后的版本使用的是ThreadpoolTaskExecutor 并且不需要手动的创建当前线程池(但往往我们…

多线程基础(五)ThreadLocal与四种引用

一、ThreadLocal ThreadLocal&#xff1a;解决每个线程绑定自己的值&#xff0c;存放线程的私有数据。 public class ThreadLocalTest {public static ThreadLocal local new ThreadLocal();public static void main(String[] args) {if(local.get() null){local.set("…

加成序列 dfs 迭代加深 java

&#x1f351; 加成序列 满足如下条件的序列 X X X&#xff08;序列中元素被标号为 1 、 2 、 3 … m 1、2、3…m 1、2、3…m&#xff09;被称为“加成序列”&#xff1a; KaTeX parse error: Undefined control sequence: \[ at position 2: X\̲[̲1\]1KaTeX parse error…

一文读懂MVCC:数据库中的并发读写利器!

大家好&#xff0c;我是你们的小米&#xff0c;一个积极活泼、喜好分享技术的小伙伴。今天&#xff0c;我想和大家聊一聊数据库领域的一个重要话题——MVCC多版本并发控制。MVCC是MySQL和其他一些数据库系统中常用的并发控制技术&#xff0c;通过它&#xff0c;我们可以在高并发…

如何用 Python 实现所有算法?

学会了 Python 基础知识&#xff0c;想进阶一下&#xff0c;那就来点算法吧&#xff01;毕竟编程语言只是工具&#xff0c;结构算法才是灵魂。 新手如何入门 Python 算法&#xff1f; 几位印度小哥在 GitHub 上建了一个各种 Python 算法的新手入门大全。从原理到代码&#xff0…

milkV-duo的Linux的开发环境搭建

目录 写在前面 内核编译 烧录失败的示例&#xff08;这种情况下就和插上空卡一样) 进入系统 串口进入 SSH接入 写在前面 基本上大部分的问题都能在开源社区上得到答案,记录下我遇到的问题. 附上开源社区 MilkV Community 这里的引脚图和板子的丝印有点对不上&#xff…

竞赛中常用的Python 标准库

对竞赛中常用得标准库进行解析和给出代码模板 目录 1.functools 1.1 cmp_to_key 1.2 lru_cache&#xff08;记忆化存储&#xff0c;加快递归速度&#xff09; 2.collections 2.1 deque 2.1.1 单调对列实现 2.1.2 BFS广搜 3.sys 3.1 sys.maxsize 3.2 sys.exit() 3.…

使用python的plot绘制loss、acc曲线,并存储成图片

使用 python的plot 绘制网络训练过程中的的 loss 曲线以及准确率变化曲线&#xff0c;这里的主要思想就时先把想要的损失值以及准确率值保存下来&#xff0c;保存到 .txt 文件中&#xff0c;待网络训练结束&#xff0c;我们再拿这存储的数据绘制各种曲线。 其大致步骤为&#x…

代码自动生成工具——TableGo(实例演示)

一、常用的代码生成器工具介绍 在SpringBoot项目开发中&#xff0c;为了提高开发效率&#xff0c;我们经常需要使用代码自动生成工具来生成一些重复性的代码&#xff0c;比如实体类、DAO、Service、Controller等等。下面介绍几个常用的代码自动生成工具&#xff1a; ①、MyBat…

如何在Linux 启用组播

第一章: 前言 多播技术&#xff0c;也被称为“组播”&#xff0c;是一种网络通信机制&#xff0c;它允许一个节点&#xff08;发送者&#xff09;向一组特定的节点&#xff08;接收者&#xff09;发送信息。这种方式在网络编程中非常有用&#xff0c;因为它可以大大提高效率和…

深度学习(Pytorch):Softmax回归

Softmax简介 Softmax回归是一个用于多类分类问题的线性模型&#xff0c;它是从Logistic回归模型演变而来的。Softmax回归与Logistic回归类似&#xff0c;但是输出不再是二元的&#xff0c;而是多类的。Softmax回归引入了softmax激活函数来将输出转换为合理的概率分布。与线性回…

HCIE-Cloud Computing LAB备考--第五题:规划--Type13练习--记忆技巧+默写

对LLD表,交换机接口表,ensp配置进行练习,如下图,设置答案和空白表,进行默写,汇总自己的容易犯的错误 LLD表默写思路 交换机接口配置表默写思路 以Type3为例,同颜色复制即可,共用ST.P0是A25,ST.P2是A21,FS是ST.P0是A21,ST.P2是A21。 ensp配置默写思路 特点: 所…

一步一步学习 Stable Diffusion

一步一步学习 Stable Diffusion 0. 背景1. 安装2. 汉化3. 安装 sd-webui-controlnet 插件4. 安装 sd-webui-segment-anything 插件5. 安装 ultimate-upscale 插件6. 安装 SadTalker 插件7. 下载和配置 VAE 模型8. 使用 ChilloutMix 模型99. 未完待续 0. 背景 网上看了很多 Sta…

priority_queue(优先级队列)

priority_queue 1. priority_queue的介绍及使用1.1 priority_queue的介绍1.2 priority_queue的使用1.2.1 constructor(构造)1.2.2 empty1.2.3 size1.2.4 top1.2.5 emplace1.2.6 push、pop、swap 1.3 数组中第K个大的元素 2.priority_queue的深度剖析及模拟实现 1. priority_que…

Makerbase SimpleFOC ESP32例程4 双电机闭环速度测试

Makerbase SimpleFOC ESP32例程4 双电机闭环速度测试 第一部分 硬件介绍 1.1 硬件清单 序号品名数量1ESP32 FOC V1.0 主板12YT2804电机2312V电源适配器14USB 线156pin杜邦线2 注意&#xff1a;YT2804是改装的云台无刷电机,带有AS5600编码器&#xff0c;可实现360连续运转。…

柔性作业车间调度

1柔性车间作业调度 个工件 要在 台机器 上加工。每个工件包含一道或多道工序&#xff0c;工序顺序是预先确定的&#xff0c;每道工序可以在多台不同加工机器上进行加工&#xff0c;工序的加工时间随加工机器的不同而不同。调度目标是为每道工序选择最合适的机器、确定每台机器…