【C++修炼秘籍】Stack和Queue

【C++修炼秘籍】STL-Stack和Queue

☀️心有所向,日复一日,必有精进

☀️专栏《C++修炼秘籍》

☀️作者:早凉

☀️如果有错误,烦请指正,如有疑问可私信联系;


目录

【C++修炼秘籍】STL-Stack和Queue

前言

一、stack和queue介绍

二、stack和queue的使用/接口介绍

stack接口

queue接口

三、容器适配器 (container adapter)

四、stack和queue模拟实现

 stack模拟实现

queue 模拟实现

deque了解

deque缺陷 

总结


前言

stack是一个先进后出(Frist In Last Out,FILO)的数据结构。只有一个出口,允许插入,删除,取栈顶元素,但除了最顶端,不能有任何方法存取其他元素,不允许任何遍历行为,所以stack不允许有遍历行为;

queue是一个先进先出(First In First Out,FIFO)数据结构。有两个出口,queue允许插入、删除,从尾端加入元素,取得头端加入元素。但是除了尾端可以加入,最头端可以去出元素外,没有任何方法存取元素,所以queue也不允许有遍历行为。


一、stack和queue介绍

之前学习过vector和list,我们如果使用vector和list来实现stack和queue多方便,其实从官方文档中看stack和queue不归为容器,stack和queue由底层容器完成工作,所以stack和queue是容器适配器container adapter或者称容器配接器;

二、stack和queue的使用/接口介绍

stack接口

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

queue接口

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

三、容器适配器 (container adapter)

容器适配器实际上是一种设计模式,对adapter的样式定义如下:将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作。其实简单的来说就是将一个类的接口转换成客户希望的另外一个接口。就像我们出国一样不同的国家电源接口是不一样的,我们需要购买转接头才能正常使用;

其实迭代器模式也是设计模式,大家可以参考相关文档。

四、stack和queue模拟实现

我们知道栈可以有数组栈和链栈或者队列,

属性:

template<class T>
class stack
{
    private:
    T*_a;
    int _top;
    int _capacity;
}

通过适配器模式,我们可以用已有的元素封装转换在直接使用

template<class T,class Container=vector<T>>
class stack
{ 
    private:
    Container _con;
}

使用时我们可以使用其他容器,数组栈,链式栈均可;

stack<int,vector<int>>st1;
​
stack<int,list<int>>st2;

queue用vector不好,头删有问题;所以queue直接用list来当默认容器;

官方底层用的deque,还是比较简单的这里就直接给出 

 stack模拟实现

#pragma once
//#include<vector>
#include<deque>
namespace my{
	//template<class T, class Containor = vector<T> >
	template<class T, class Container = deque<T>>
	class stack{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}
		void pop()
		{
			_con.pop_back();
		}
		const T& top()
		{
			return _con.back();
		}
		bool empty()
		{
			return _con.empty();
		}

		size_t size()
		{
			return _con.size();
		}
	private:
		Container  _con;
	};
}

queue 模拟实现

#pragma once
#include<deque>
namespace my{
	//template<class T, class Containor = list<T> >
	template<class T, class Container = deque<T>>
		class queue{
		public:
			void push(const T& val)
			{
				_con.push_back(val);
			}
			void pop()
			{
				_con.pop_front();
			}
			const T& front()
			{
				return _con.front();
			}

			const T& back()
			{
				return _con.back();
			}
			bool empty()
			{
				return _con.empty();
			}

			size_t size()
			{
				return _con.size();
			}
		private:
			Container  _con;
		};
}

  ❓这里为什么用的底层容器是deque?deque是什么?

vector头部中部插入删除效率低,而且扩容效率也低;

list不支持随机访问,CPU高速缓存命中低;有没有兼具vector和list优点的容器?诶,有就是deque(Double ended queue)

说是双端队列,但不符合FIFO

支持头删,支持随机访问

功能上功能完美所以为什么要有vector和list呢?

所以说着肯定会有问题呀;接下来我们详细介绍细节。

deque了解

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作。

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,(版本实现不同,这里举例一个)

多个buffer数组组成,有一个中控数组,是个指针数组,指向下一个buffer,如果数组满了就在开一个buffer,头插就前面排一个buffer

就是如图一样的结构 。按理说不是连续的空间,但是怎么假设成连续空间,我们看看迭代器;

 

——《STL源码剖析》  

deque缺陷 

  ❓想想随机访问怎么办?vector的随机访问怎么办?

随机访问就是原生指针,

而这里就是先选在第几个buffer在算是这个buffer的第几个;

下标的随机访问有一定的小号,没有vector快。

中间插入删除,也有一定消耗,相比list的中间插入删除,不够极致。

做栈和队列的默认容器确实不错;

头尾插入删除多,尽量少的随机访问还是不错的;

为什么底层要用deque

1. stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或者两端进行操作。
2. 在stack中元素增长时,deque比vector的效率高(扩容时不需要搬移大量数据);queue中的元素增长时,deque不仅效率高,而且内存使用率高。
 


总结

deque这种太少用了,我们大概知道结构就是,知道在何时使用deque比较好。头尾插入删除多,尽量少的随机访问可以使用。

我们也要学会类似于适配器这样的设计模式,对于写代码有所帮助。

好了,下期见,各位!

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

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

相关文章

dnSpy调试工具二次开发2-输出日志到控制台

本文在上一篇文章的基础上继续操作&#xff1a; dnSpy调试工具二次开发1-新增菜单-CSDN博客 经过阅读dnSpy的源码&#xff0c;发现dnSpy使用到的依赖注入用了MEF框架&#xff0c;所以在源码中可以看到接口服务类的上面都打上了Export的特性或在构造方法上面打上ImportingConst…

尚无忧球馆助教系统源码,助教小程序源码,助教源码,陪练系统源码

特色功能&#xff1a; 不同助教服务类型选择 助教申请&#xff0c;接单&#xff0c;陪练师入住&#xff0c;赚取外快 线下场馆入住 设置自己服务 城市代理 分销商入住 优惠券 技术栈&#xff1a;前端uniapp后端thinkphp 独立全开源

翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一

随着 OpenAI 在多模态方面的最新进展&#xff0c;想象一下将这种能力与视觉理解相结合。 现在&#xff0c;您可以在 Streamlit 应用程序中使用 GPT-4 和 Vision&#xff0c;以&#xff1a; 从草图和静态图像构建 Streamlit 应用程序。帮助你优化应用的用户体验&#xff0c;包…

NoSQL基本内容

第一章 NoSQL 1.1 什么是NoSQL NoSQL&#xff08;Not Only SQL&#xff09;即不仅仅是SQL&#xff0c;泛指非关系型的数据库&#xff0c;它可以作为关系型数据库的良好补充。随着互联网web2.0网站的兴起&#xff0c;非关系型的数据库现在成了一个极其热门的新领域&#xff0c;…

vulnhub靶场之Five86-2

一.环境搭建 1.靶场描述 Five86-2 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing. The ultimate goal of this challenge is to get root and to read the one and only flag. Linux skills and fa…

2024年阿里云幻兽帕鲁Palworld游戏服务器优惠价格表

自建幻兽帕鲁服务器租用价格表&#xff0c;2024阿里云推出专属幻兽帕鲁Palworld游戏优惠服务器&#xff0c;配置分为4核16G和4核32G服务器&#xff0c;4核16G配置32.25元/1个月、10M带宽66.30元/1个月、4核32G配置113.24元/1个月&#xff0c;4核32G配置3个月339.72元。ECS云服务…

Java项目实战--瑞吉外卖DAY03

目录 P22新增员工_编写全局异常处理器 P23新增员工_完善全局异常处理器并测试 p24新增员工_小结 P27员工分页查询_代码开发1 P28员工分页查询_代码开发2 P22新增员工_编写全局异常处理器 在COMMON新增全局异常捕获的类&#xff0c;其实就是代理我们这些controlle。通过aop把…

【C语言】深入理解指针(3)数组名与函数传参

正文开始——数组与指针是紧密联系的 &#xff08;一&#xff09;数组名的理解 &#xff08;1&#xff09;数组名是数组首元素的地址 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *parr &arr[0]; 上述代码通过&arr[0] 的方式得到了数组第一个元素的地址&#xff0c;…

基于DataKit迁移MySQL到openGauss

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

RTP工具改进(五)--使用qt

前篇 第四篇 RTP工具改进(四) - rtmp协议推送 前面使用的工具一直为mfc&#xff0c;今天将使用qt 来做界面&#xff0c;使用qt 来进行程序和协议的编写&#xff0c;qt部分目前还不包括rtp ps流和rtmp&#xff0c;暂时只有rtp 直接传输&#xff0c;关于rtmp协议和ps流协议&…

MySQL--创建数据表(5)

创建 MySQL 数据表需要以下信息&#xff1a; 表名表字段名定义每个表字段的数据类型 语法 以下为创建 MySQL 数据表的 SQL 通用语法&#xff1a; CREATE TABLE table_name (column1 datatype,column2 datatype,... );参数说明&#xff1a; table_name 是你要创建的表的名称…

“海洋天堂——助成长计划”走进安徽省科学技术馆

为了助力困境儿童、青少年有效地参与社会生活&#xff0c;培养他们团队精神&#xff0c;引导他们掌握社会规则&#xff0c;增强自信&#xff0c;合肥市庐阳区为民社会工作服务中心于2024年1月24日上午&#xff0c;组织有四名老师带领18名困境儿童、青少年&#xff0c;通过徒步、…

使用PHP自定义一个加密算法,实现编码配合加密,将自己姓名的明文加密一下

<meta charset"UTF-8"> <?phpfunction customEncrypt($lin, $key mySecretKey){// 定义一个简单的替换规则$li array(L > M, I > Y, Y > O, A > N, E > Q, );$yan ;for($i 0; $i < strlen($lin); $i){$char $lin[$i];if(isset($li[…

Self-Attention 和 Multi-Head Attention 的区别——附最通俗理解!!

文章目录 前言 一、简要介绍 二、工作流程 三、两者对比 四、通俗理解 前言 随着Transformer模型的迅速普及&#xff0c;Self-Attention&#xff08;自注意力机制&#xff09;和Multi-Head Attention&#xff08;多头注意力机制&#xff09;成为了自然语言处理&#xff08;NLP…

sqli-labs靶场第七关

7、第七关 id1 --单引号报错,id1" --双引号不报错,可以判断是单引号闭合 id1) --也报错&#xff0c;尝试两个括号闭合&#xff0c;id1)) --不报错 接下来用脚本爆库 import stringimport requestsnumbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] letters2 list(string.ascii_…

1.【Vue3】前端开发引入、Vue 简介

1. 前端开发引入 1.1 前端开发前置知识 通过之前的学习&#xff0c;已经通过 SpringBoot 和一些三方技术完成了大事件项目的后端开发。接下来开始学习大事件项目的前端开发&#xff0c;前端部分借助两个框架实现&#xff1a; Vue3&#xff08;一个 JS 框架&#xff09;基于 …

一篇博客读懂排序

目录 一、常见的排序 二、冒泡排序 2.1基本思想&#xff1a; 2.2代码&#xff1a; 三、插入排序 3.1基本思想&#xff1a; 3.2思路讲解&#xff1a; 3.3代码&#xff1a; 3.4时间复杂度&#xff1a; 四、希尔排序 4.1基本思路&#xff1a; 4.2思路讲解&#xff1a;…

openssl3.2 - 测试程序的学习 - test\acvp_test.c

文章目录 openssl3.2 - 测试程序的学习 - test\acvp_test.c概述笔记要单步学习的测试函数备注END openssl3.2 - 测试程序的学习 - test\acvp_test.c 概述 openssl3.2 - 测试程序的学习 将test*.c 收集起来后, 就不准备看makefile和make test的日志参考了. 按照收集的.c, 按照…

IPv6报文格式(全网最详细)

IPv6报文格式 报文格式 图1 IPv6报文头格式 表1 IP头字段解释 字段长度含义Version4比特 4&#xff1a;表示为IPV4&#xff1b;6&#xff1a;表示为IPV6。Traffic class8比特流量类别。该字段及其功能类似于IPv4的业务类型字段。该字段以区分业务编码点&#xff08;DSCP&…

C语言——操作符详解2

目录 0.过渡0.1 不创建临时变量&#xff0c;交换两数0.2 求整数转成二进制后1的总数 1.单目表达式2. 逗号表达式3. 下标访问[ ]、函数调用( )3.1 下标访问[ ]3.2 函数调用( ) 4. 结构体成员访问操作符4.1 结构体4.1.1 结构体的申明4.1.2 结构体变量的定义和初始化 4.2 结构体成…