【C++】stack和queue的使用及模拟实现(含deque的简单介绍)

news2025/3/19 7:55:08

文章目录

  • 前言
  • 一、deque的简单介绍
    • 1.引入deque的初衷
    • 2.deque的结构
    • 3.为什么选择deque作为stack和queue的底层默认容器
  • 二、stack
    • 1.stack的介绍
    • 2.stack的使用
    • 3.stack的模拟实现
  • 三、queue
    • 1.queue的介绍
    • 2.queue的使用
    • 3.queue的模拟实现


前言

一、deque的简单介绍(引入deque的初衷、deque的结构 以及 选择deque作为stack和queue的底层默认容器的原因)
二、stack和queue的使用及模拟实现


一、deque的简单介绍

1.引入deque的初衷

vector的优点是支持随机访问,缺点是插入删除元素的效率很低(除了尾插尾删);list的优点是在任意位置插入和删除元素的效率级高,缺点是不支持随机访问。
deque想要融合vector和list的优点弥补它们各自的缺陷,但是融合的并不完美。deque支持随机访问,但访问效率不如vector;而且还有一个致命缺陷:在中间位置的插入和删除效率极低,甚至低于vector;但deque在头尾插入和删除的效率特别高,优于vector,跟list效率同级别

2.deque的结构

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
在这里插入图片描述
deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,用一个指针数组map管理一段段小空间的起始地址,实际deque类似于一个动态的二维数组,其底层结构如下图所示:
在这里插入图片描述

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

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

  1. 高效的头尾操作 deque支持在两端以 O ( 1 ) O(1) O(1)时间复杂度进行插入和删除操作,这完美适配:

    • stack(后进先出):仅需尾部操作(push_back/pop_back)。
    • queue(先进先出):需要头部删除(pop_front)和尾部插入(push_back)。
  2. 内存管理的灵活性

    • 分段连续存储deque由多个固定大小的块组成,扩容时只需分配新块,不需要像vector那样复制整个数组到新位置,deque的扩容成本更低。
    • 避免内存浪费:与list的节点式存储相比,deque的分块结构更紧凑,空间利用率更好。
      list的底层节点不连续,小节点容易造成内存碎片,空间利用率低,缓存利用率低)

总结
虽然vector尾部操作高效,但头部操作低效,而且deque的扩容成本更低。 deque头尾操作性能跟list同级别,但综合性能优于list(缓存友好)。所以最终选择了queue作为stack和queue的底层默认容器。

二、stack

1.stack的介绍

栈是⼀种特殊的线性表,其只允许在固定的⼀端进行插入和删除元素操作。进行数据插入和删除操作的⼀端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出的原则。

压栈(push):栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈(pop):栈的删除操作叫做出栈。出数据也在栈顶。

在这里插入图片描述

在这里插入图片描述
stake作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,stake提供一组特定的成员函数来访问其元素。
stack是一种后进先出的特殊线性数据结构,因此只要具push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector、list 和 deque都可以。默认情况下,如果没有为stake实例化指定容器类,则使用标准容器deque。

适配器是一种设计模式,该种模式是将一个类的接口转换成客户希望的另外一个接口。
虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque作为其底层容器类。

2.stack的使用

在这里插入图片描述

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

int main()
{
	stack<int> sta;
	sta.push(9);
	sta.push(9);
	sta.push(6);
	sta.push(5);
	sta.push(2);
	sta.push(0);
	while (!sta.empty())
	{
		cout << sta.top() << ' ';
		sta.pop();
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

3.stack的模拟实现

#include <deque>
using namespace std;
namespace zh
{
	template <class T, class Container = deque<T> >
	class stack
	{
	public:
		stack()
		{ }

		bool empty() const
		{
			return con.empty();
		}

		size_t size() const
		{
			return con.size();
		}

		T& top()
		{
			return con.back();
		}
		const T& top() const
		{
			return con.back();
		}

		void push(const T& val)
		{
			con.push_back(val);
		}

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

		void swap(stack& x)
		{
			con.swap(x.con);
		}

	private:
		Container con;
	};
}

三、queue

1.queue的介绍

队列只允许在⼀端进行插入数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先出的特性。

入队列:进行插入操作的⼀端称为队尾
出队列:进行删除操作的⼀端称为队头

在这里插入图片描述
在这里插入图片描述
queue作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。
queue是一种先进先出的特殊线性数据结构,因此只要具push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list 和 deque都可以。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

2.queue的使用

在这里插入图片描述

函数说明接口说明
queue()构造空的队列
empty()检测队列是否为空
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素val入队列
pop()将队头元素出队列
#include <iostream>
#include <queue>
using namespace std;

int main()
{
	queue<int> que;
	que.push(9);
	que.push(9);
	que.push(6);
	que.push(5);
	que.push(2);
	que.push(0);
	while (!que.empty())
	{
		cout << que.front() << ' ';
		que.pop();
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

3.queue的模拟实现

#include <deque>
using namespace std;
namespace zh
{
	template <class T, class Container = deque<T> >
	class queue
	{
	public:
		queue()
		{ }

		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() const
		{
			return con.back();
		}

		void push(const T& val)
		{
			con.push_back(val);
		}

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

		void swap(queue& x)
		{
			con.swap(x.con);
		}

	private:
		Container con;
	};
}

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

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

相关文章

MySQL原理:逻辑架构

目的&#xff1a;了解 SQL执行流程 以及 MySQL 内部架构&#xff0c;每个零件具体负责做什么 理解整体架构分别有什么模块每个模块具体做什么 目录 1 服务器处理客户端请求 1.1 MySQL 服务器端逻辑架构说明 2 Connectors 3 第一层&#xff1a;连接层 3.1 数据库连接池(Conn…

ora-600 ktugct: corruption detected---惜分飞

接手一个oracle 21c的库恢复请求,通过Oracle数据库异常恢复检查脚本(Oracle Database Recovery Check)脚本检测之后,发现undo文件offline之后,做了resetlogs操作,导致该文件目前处于WRONG RESETLOGS状态 尝试恢复数据库ORA-16433错误 SQL> recover datafile 1; ORA-00283:…

Houdini :《哪吒2》神话与科技碰撞的创新之旅

《哪吒2》&#xff08;即《哪吒之魔童闹海》&#xff09;截止至今日&#xff0c;荣登全球票房榜第五。根据猫眼专业版数据&#xff0c;截至2025年3月15日&#xff0c;《哪吒2》全球累计票房&#xff08;含预售及海外&#xff09;超过150.19亿元&#xff0c;超越《星球大战&…

flink 写入es的依赖导入问题(踩坑记录)

flink 写入es的依赖导入问题(踩坑记录) ps&#xff1a;可能只是flink低版本才会有这个问题 1. 按照官网的导入方式&#xff1a; 2. 你会在运行sql-client的时候完美得到一个错误&#xff1a; Exception in thread "main" org.apache.flink.table.client.SqlClientEx…

PCL 高斯函数拟合(正太分布)

文章目录 一、简介二、实现代码三、实现效果一、简介 类似于之前最小二乘法的做法,我们需要先确定目标函数: 通过最小二乘法,找到使预测值与实际数据残差平方和最小的参数: 不过由于这是一个非线性最小二乘问题,因此这里无法使用矩阵的形式之间求解它的解析解了,因此这里…

深度革命:ResNet 如何用 “残差连接“ 颠覆深度学习

一文快速了解 ResNet创新点 在深度学习的历史长河中&#xff0c;2015年或许是最具突破性的一年。这一年&#xff0c;微软亚洲研究院的何恺明团队带着名为ResNet&#xff08;残差网络&#xff09;的模型横空出世&#xff0c;在ImageNet图像分类竞赛中以3.57%的错误率夺冠&#…

Java基础与集合

参考 Java基础知识详解&#xff1a;从面向对象到异常处理-CSDN博客 2024年 Java 面试八股文&#xff08;20w字&#xff09;_java面试八股文-CSDN博客 基础知识 java概述 什么是java&#xff1f; java是一种面向对象的编程语言 java特点 面向对象&#xff08;继承&#…

【Python 算法零基础 1.线性枚举】

我装作漠视一切&#xff0c;以为这样就可以不在乎 —— 25.3.17 一、线性枚举的基本概念 1.时间复杂度 线性枚举的时间复杂度为 O(nm)&#xff0c;其中 n是线性表的长度。m 是每次操作的量级&#xff0c;对于求最大值和求和来说&#xff0c;因为操作比较简单&#xff0c;所以 …

003 SpringCloud整合-LogStash安装及ELK日志收集

SpringCloud整合-LogStash安装及ELK日志收集 文章目录 SpringCloud整合-LogStash安装及ELK日志收集1.安装ElasticSearch和kibana2.Docker安装logstash1.拉取docker镜像2.创建外部挂载目录3.拷贝容器内部文件到宿主机4.修改外部挂载文件5.运行docker容器 3.整合kibana1.进入kiba…

AI预测体彩排3新模型百十个定位预测+胆码预测+杀和尾+杀和值2025年3月18日第22弹

前面由于工作原因停更了很长时间&#xff0c;停更期间很多彩友一直私信我何时恢复发布每日预测&#xff0c;目前手头上的项目已经基本收尾&#xff0c;接下来恢复发布。当然&#xff0c;也有很多朋友一直咨询3D超级助手开发的进度&#xff0c;在这里统一回复下。 由于本人既精…

数据结构入门(1)——算法复杂度

目录 一、前言 二、数据结构 2.1数据结构的概念 2.2数据结构的组成 2.3算法 三、oj题引进 四、复杂度 4.1复杂度的概念 4.2大O渐进表示法 4.3时间复杂度 4.4时间复杂度计算示例 4.4.1示例1 4.4.2示例2 4.4.3示例3 4.4.4示例4 4.4.5示例5 4.4.6示例6 4.4.7示例7 4.4.8示例8 4.5空…

【最新版】智慧小区物业管理小程序源码+uniapp全开源

一.系统介绍 智慧小区物业管理小程序,包含小区物业缴费、房产管理、在线报修、业主活动报名、在线商城等功能。为物业量身打造的智慧小区运营管理系统,贴合物业工作场景,轻松提高物业费用收缴率,更有功能模块个性化组合,助力物业节约成本高效运营。 二.搭建环境 系统环…

DeepSeek搭建本地知识库

1. 注册硅基流动 首先&#xff0c;打开浏览器&#xff0c;访问硅基流动的官方网站。 https://account.siliconflow.cn/ 在注册页面准确输入你的手机号&#xff0c;完成账号注册。这是搭建本地知识库的第一步&#xff0c;为后续获取重要权限做准备。 成功注册后&#xff0c;进…

实验9 高级搜索技术1

实验9 高级搜索技术1 一、实验目的 &#xff08;1&#xff09;掌握高级搜索技术的相关理论&#xff0c;能根据实际情况选取合适的搜索方法&#xff1b; &#xff08;2&#xff09;进一步熟悉爬山法搜索技术&#xff0c;掌握其在搜索过程中的优缺点&#xff1b; &#xff08;3&…

【数据挖掘】Python基础环境安装配置

【数据挖掘】Python基础环境安装配置 一、摘要二、安装Python3.13.2三、安装Jupyter Notebook四、安装Numpy和Pandas以及matplotlib五、安装scikit-learn库和seaborn库 一、摘要 本文主要介绍如何在Windows上安装Python3.13.2&#xff0c;然后基于该Python版本安装Jupyter not…

【2025新版本】【谷粒商城版】Kubernetes

本文作者&#xff1a; slience_me 文章目录 【2025】Kubernetes1. docker安装2. kubernetes安装前3. kubeadm,kubelet,kubectl3.1 简介kubeadmkubeletkubectl常用指令 3.2 安装3.3 kubeadm初始化3.4 加入从节点(工作节点)3.5 安装Pod网络插件&#xff08;CNI&#xff09;3.6 Ku…

vulhub-Billu-b0x攻略

靶场下载链接 https://download.vulnhub.com/billu/Billu_b0x.zip 将kali和Billu,NAT连接 获取靶场ip arp-scan -l 使用diesearch进行目录扫描 dirsearch -u " " 查看目录中的信息 打开add.php,得到有上传文件功能的&#xff08;看到后面你会发现其实这里就可以完…

vue3+Ts+elementPlus二次封装Table分页表格,表格内展示图片、switch开关、支持

目录 一.项目文件结构 二.实现代码 1.子组件&#xff08;表格组件&#xff09; 2.父组件&#xff08;使用表格&#xff09; 一.项目文件结构 1.表格组件&#xff08;子组件&#xff09;位置 2.使用表格组件的页面文件&#xff08;父组件&#xff09;位置 3.演示图片位置 ele…

数字人本地部署之llama-本地推理模型

llama 本地服务命令 llama-server.exe -m "data/LLM/my.gguf" --port 8080 -m data/LLM/my.gguf -m 属于命令行选项&#xff0c;一般用来指定要加载的模型文件。 data/LLM/my.gguf 是模型文件的路径。gguf 格式的文件是一种用于存储语言模型权重的文件格式&…

RUOYI框架在实际项目中的应用三:Ruoyi微服务版本-RuoYi-Cloud

如需观看Ruoyi框架的整体介绍&#xff0c;请移步&#xff1a;RUOYI框架在实际项目中的应用一&#xff1a;ruoyi简介 一、Ruoyi微服务版本-Ruoyi微服务版本 1、官方资料 1&#xff1a;代码地址&#xff1a;https://gitee.com/y_project/RuoYi-Cloud.git 2&#xff1a;文档介绍…