C++第二十六弹---stack和queue的基本操作详解与模拟实现

news2025/1/12 12:15:12

  ✨个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】

目录

1. stack的介绍和使用

1.1 stack的介绍

​1.2 stack的使用

1.3 stack 模拟实现

2. queue的介绍和使用

2.1 queue的介绍

2.2 queue的使用

2.3 queue的模拟实现

3. deque的简单介绍

3.1 deque的原理介绍

3.2 deque的优势

3.3 deque的缺陷

3.4 为什么选择deque作为stack和queue的底层默认容器

总结


1. stack的介绍和使用


1.1 stack的介绍

stack文档介绍icon-default.png?t=N7T8https://cplusplus.com/reference/stack/stack/?kw=stack

1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其中元素只能从容器的一端进行元素的插入与提取操作。


2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。


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

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


4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。


1.2 stack的使用

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

将stack中尾部的元素弹出

代码演示:

void test_stack()
{
	//stack<int, deque<int>> st;
	stack<int> st;//实例化栈
	st.push(1);//入栈
	st.push(2);
	st.push(3);
	st.push(4);
	cout << "size() = " << st.size() << endl;//计算栈的元素个数
	//打印栈的元素
	while (!st.empty())//判断栈是否为空
	{
		cout << st.top() << " ";//打印栈顶元素
		st.pop();//出栈
	}
	cout << endl;
}

测试结果:

1.3 stack 模拟实现

首先我们先看看C语言中是如何定义栈的基本结构,如下:

//C语言版本
template<class T>
struct stack
{
	T* _a;        //存放数据,使用动态开辟内存空间
	int _top;     //数据个数,top-1为栈顶下标
	int _capacity;//容量
};

在C++中我们会使用容器适配器来实现栈,即是对特定类封装作为其底层的容器并提供一组特定的成员函数来访问其元素。

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

C++实现栈的基本结构如下: 

//T为容器中元素的类型,Container为容器的类型,默认用std::vector<T>
template<class T, class Container = vector<T>>
class stack
{
private:
	Container _con;
};

Container是一个模板参数,允许我们自己定义底层数据结构默认容器为stl库中的vector<T>,也可以是stl中的其他容器,只要能达到后进先出即可。

栈的相关函数实现如下:

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;
};

注意:为了保证与库中的stack容器名字不冲突,尽量使用自己的命名空间域来实现栈。 

2. queue的介绍和使用


2.1 queue的介绍

1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。


2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列从队头出队列。


3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:

  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列


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

2.2 queue的使用

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

代码演示:

void test_queue()
{
	//queue<int, deque<int>> q;
	queue<int> q;//实例化队列
	q.push(1);//入队
	q.push(2);
	q.push(3);
	q.push(4);
	cout << "size() = " << q.size() << endl;//队列元素个数
	//打印队列元素
	while (!q.empty())//判断是否为空
	{
		cout << q.front() << " ";//打印队头数据
		q.pop();//出队
	}
	cout << endl;
}

代码测试: 

2.3 queue的模拟实现


因为queue的接口中存在头删和尾插,而使用vector来封装效率太低,因此可以借助list来模拟实现queue。


模拟实现如下:

template<class T, class Container = list<T>>//不能使用vector,没有头删
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;
};


上面我们确实通过list容器实现了queue容器,但是为什么stl库默认使用的是deque容器呢?下面我们就来了解了解deque容器。


3. deque的简单介绍


3.1 deque的原理介绍


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

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:

那deque是如何借助其迭代器维护其假想连续的结构呢?

3.2 deque的优势

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是比vector高。

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外空间。

3.3 deque的缺陷


deque有一个致命缺陷不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。


3.4 为什么选择deque作为stack和queue的底层默认容器


stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

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

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

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

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

相关文章

5.31.15 使用图像到图像转换和 YOLO 技术对先前的乳房 X 光检查结果中的异常进行早期检测和分类

在本研究中&#xff0c;我们研究了基于 You-Only-Look-Once (YOLO) 架构的端到端融合模型的有效性&#xff0c;该模型可同时检测和分类数字乳房 X 光检查中的可疑乳腺病变。包括四类病例&#xff1a;肿块、钙化、结构扭曲和正常&#xff0c;这些病例来自包含 413 个病例的私人数…

一次曝 9 个大模型,「字节 AI」这一年都在做什么?

字节跳动的大模型家族&#xff0c;会长出下一个抖音吗&#xff1f; 整个 2023 年&#xff0c;字节并没有对外官宣其内部自研的大模型。外界一度认为&#xff0c;大模型这一技术变革&#xff0c;字节入场晚了。梁汝波在去年底的年会上也提到了这一点&#xff0c;他表示「字节对…

【全开源】露营地管理系统小程序源码(ThinkPHP+FastAdmin+UniApp)

专为露营业务设计开发小程序应用。平台拥有多角色管理&#xff0c;同时具有营位预定、门票购买等功能模块。 &#x1f525;露营地管理系统小程序&#xff1a;轻松掌控你的露营帝国&#x1f3d5;️ &#x1f4cc;一、引言&#xff1a;露营地管理的新时代 随着露营文化的兴起&a…

❤vue2项目webpack打包的优化策略

❤ vue2项目webpack打包的优化策略 &#xff08;优化前&#xff09; 现在我们的打包时间为&#xff1a; >打包体积大小为&#xff1a; 1、去除开发环境和生产环境提示以及日志 开发环境和生产环境的打印处理 生产环境去除console.log打印的两种方式 通过环境变量控制co…

知识图谱的应用---社交网络

文章目录 社交网络典型应用 社交网络 社交网络已成为发展最快的互联网应用&#xff0c;社交网络用户不仅仅是信息的接受者&#xff0c;也成为了信息的制造、加工和传播者&#xff0c;通过关注、被关注的方式形成了一张张庞杂繁复的用户关系网。随着社交网络中用户及信息急速增长…

数新网络签单国泰君安:利用数据服务平台提升金融业务用数能力

近日&#xff0c;数新网络与国泰君安证券股份有限公司&#xff08;以下简称“国泰君安”&#xff09;达成了数据服务平台升级项目的签约。这一项目的推进将更好地服务于国泰君安内部业务部门的数据需求&#xff0c;帮助数据平台更加有效地实现提升业务响应效率的目标&#xff0…

【Linux文件篇】系统文件、文件描述符与重定向的实用指南

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;相信大家对文件都不会太陌生、也不会太熟悉。在没有学习Linux操作系统时&#xff0c;我们在学习C或C时都学过如何去创建、打开、读写等待文件的操作&#xff0c;知道一些语言级别的一些接口与函数。但…

怎样把便签里的内容移到桌面?桌面便签软件使用方法

每次打开电脑&#xff0c;我总是被满屏的文件和图标弄得眼花缭乱。那些记录在各式各样便签里的重要事项&#xff0c;经常被埋没在这信息的海洋中&#xff0c;找起来真是头疼。想必很多人都有过这样的困扰&#xff1a;如何在繁杂的桌面环境中&#xff0c;一眼就看到自己需要提醒…

问题:以下被纳入代理资产风险分类管理的业务包括() #媒体#知识分享

问题&#xff1a;以下被纳入代理资产风险分类管理的业务包括&#xff08;&#xff09; A&#xff0e;非标准化理财投资业务 B&#xff0e;特定债权投资业务 C&#xff0e;委托债权代理业务 D&#xff0e;非标准化代理销售业务 参考答案如图所示

HTML静态网页成品作业(HTML+CSS)—— 兰蔻化妆品网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

NAT

文章目录 1.NAT是什么2.NAT功能3.NAT优缺点4.NAT作用工作原理5.NAT 静态 动态5.1静态静态配置1.全局模式下设置静态NAT2.接口上设置静态NAT 5.2动态动态配置测试 6.PAT多路复用 PAT NAPT Easyip NAT server6.1PAT端口多路复用PAT作用 1.NAPT配置测试 2.EasyIp配置测试 3.NAT se…

Fegin如何传参form-data文件

Form-data传输file参数&#xff0c;这个大家都比较清楚&#xff0c;那么针对于Fegin参数file参数该如何操作呢&#xff01;下面截图来找到对应的参数关系。 一、之前我们在postMan中是这种传参的&#xff0c;那么如果使用Feigin来传输文件File 二、在Fegin中传form-data参数&a…

Qt系统相关

本文目录 1.Qt事件事件的处理标签事件鼠标事件滚轮事件按键事件定时器事件窗口事件事件派发器 2.Qt文件操作QFile的基本使用 3.Qt多线程使用线程线程锁connect的第五个参数 条件变量和信号量 4.Qt网络编程UDP SocketTCP SocketQTcpServerQTcpSocket HTTP的编写 5.QT多媒体播放音…

【区块链】深入解析Proof of Work (PoW): 区块链技术的核心驱动力

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入解析 Proof of Work (PoW): 区块链技术的核心驱动力引言一、PoW基本概念1.1…

UNetMultiLane 多车道线、车道线类型识别

基于UNet 分割模型增加了检测头来识别车道线的类型&#xff08;单实线、双黄线等10种&#xff09;&#xff0c;同时可以识别出"所在车道"和"车道线类型"。 训练代码【训练练手代码】 1 数据说明 基于开源数据集 VIL100。其中数据标注了所在的六个车道的车…

大福利!微信付费进群源码

微信付费进群源码 前言效果图搭建教程源码领取下期更新预报 前言 1、修复SQL表 2、修复支付文件 3、修复支付图标不显示 4、修复定位、分销逻辑、抽成逻辑 5、新增支持源支付、易支付的支付接口 6、修复官方微信、支付宝支付接口文件 本来早就可以完工的&#xff0c;电脑…

苹果WWDC 2024速览

引言 2024年苹果全球开发者大会&#xff08;WWDC&#xff09;在充满科技感的苹果园区拉开帷幕&#xff0c;本次大会发布了众多令人振奋的软硬件更新&#xff0c;包括Vision OS 2、iOS 18、watchOS 11和macOS Sequoia的重大创新。本文将详细解读这些更新&#xff0c;为您展示它…

来自中国信通院的认可!上海斯歌受邀加入“EP-Link 智能流程推进计划”

5月30日&#xff0c;由中国信息通信研究院主办的“EP-Link 智能流程推进计划”周年产业研讨会在北京隆重召开。会上&#xff0c;在众多领袖专家、行业翘楚的见证下&#xff0c;上海斯歌被中国信息通信研究院授予“EP-Link 智能流程推进计划”成员单位证书&#xff0c;正式加入该…

Vxe UI vxe-modal 实现窗口的最大化与最小化,实现弹出多窗口

Vxe UI vue vxe-modal 实现窗口的最大化与最小化&#xff0c;实现弹出多窗口 通过js方式调用 js方式脱离模板&#xff0c;每次创建是多个实例。 mask&#xff1a;关闭遮罩层&#xff0c;如果不关闭则会显示遮罩层&#xff0c;就不能实现同时操作多窗口 lockView&#xff1a;…

IDA反调试、反汇编解决方案

IDA全称为Interactive Disassembler Professional&#xff0c;是一款交互式静态反汇编工具&#xff0c;它可以直接反汇编出二进制文件的汇编代码&#xff0c;是逆向分析领域最强大的工具之一。 IDA支持Windows、Linux等多平台与数十种指令集&#xff0c;凭借着泛用性与友好的图…