【C++】stack和queue

个人主页 : zxctscl
如有转载请先通知

文章目录

  • 1. stack的介绍和使用
    • 1.1 stack的介绍
    • 1.2 stack的使用
    • 1.3 stack的模拟实现
  • 2. queue的介绍和使用
    • 2.1 queue的介绍
    • 2.2 queue的使用
    • 2.3 queue的模拟实现
  • 3. 容器适配器
    • 3.1 概念
    • 3.2 STL标准库中stack和queue的底层结构
    • 3.3 deque的简单介绍
      • 3.3.1 deque的原理介绍
      • 3.3.2 deque的缺陷
    • 3.4 为什么选择deque作为stack和queue的底层默认容器

1. stack的介绍和使用

1.1 stack的介绍

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。
  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:
    empty:判空操作
    back:获取尾部元素操作
    push_back:尾部插入元素操作
    pop_back:尾部删除元素操作
  4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。
    在这里插入图片描述

1.2 stack的使用

在这里插入图片描述
stack不支持迭代器

1.3 stack的模拟实现

栈实际是一种特殊的vector,因此使用vector完全可以模拟实现stack。

#pragma once
#include<vector>


namespace bit
{

	template<class T, class Container = vector<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}

		const T& top()
		{
			return _con.back();
		}
	private:
		Container _con;
	};
}

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的使用

在这里插入图片描述

2.3 queue的模拟实现

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

#include <list>
namespace bite
{
	template<class T>
	class queue
	{
	public:
		queue() {}
		void push(const T& x) 
		{ 
			_c.push_back(x);
		}

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

		T& back() 
		{ 
			return _c.back();
		}

		const T& back()const 
		{
			return _c.back();
		}
		T& front() 
		{ 
			return _c.front(); 
		}

		const T& front()const
		{
			return _c.front();
		}

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

		bool empty()const 
		{ 
			return _c.empty(); 
		}
	private:
		std::list<T> _c;
	};
}

3. 容器适配器

3.1 概念

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

在这里插入图片描述

3.2 STL标准库中stack和queue的底层结构

虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配
器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque,比如:
在这里插入图片描述
在这里插入图片描述

3.3 deque的简单介绍

3.3.1 deque的原理介绍

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
在这里插入图片描述
deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:
在这里插入图片描述
双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:
在这里插入图片描述
那deque是如何借助其迭代器维护其假想连续的结构呢?
在这里插入图片描述

3.3.2 deque的缺陷

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。
与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。
但是,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的优点,而完美的避开了其缺陷。

有问题请指出,大家一起进步!!!

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

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

相关文章

@RequestParam和@PathVariable的区别

同样都是接收URL中的参数&#xff0c;RequestParam和PathVariable有什么区别呢&#xff1f;

随手集☞Spring知识盘点

概述 定义 Spring框架的提出者是程序员Rod Johnson&#xff0c;他在2002年最早提出了这个框架的概念&#xff0c;随后创建了这个框架。Spring框架的目标是简化企业级Java应用程序的开发&#xff0c;通过提供一套全面的工具和功能&#xff0c;使开发者能够更加高效地构建高质量…

Prometheus+grafana环境搭建MongoDB(docker+二进制两种方式安装)(五)

由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前四篇mongodb的exporter坑也挺多总结一下各种安装方式&#xff0c;方便后续考古。 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana环境搭建rabb…

5分钟润色一篇论文:ChatGPT意味着什么?Nature连发两篇文章探讨

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

服务器硬件构成与性能要点:CPU、内存、硬盘、RAID、网络接口卡等关键组件的基础知识总结

文章目录 服务器硬件基础知识CPU&#xff08;中央处理器&#xff09;内存&#xff08;RAM&#xff09;硬盘RAID&#xff08;磁盘阵列&#xff09;网络接口卡&#xff08;NIC&#xff09;电源散热器主板显卡光驱 服务器硬件基础知识 服务器是一种高性能计算机&#xff0c;用于在…

第1章:芯片及引脚介绍

芯片及引脚介绍 1&#xff1a; 芯片介绍1.1&#xff1a;芯片系列1.2 &#xff1a;STM32F103C8T6型号的介绍 2&#xff1a;引脚2.1&#xff1a;寄存器2.2&#xff1a;最小系统板 3&#xff1a;最小系统板的引脚3.1&#xff1a;特殊引脚3.2&#xff1a;普通引脚3.3&#xff1a;最…

Linux之信号

1.常见信号 虽然最开始的编号是1&#xff0c;最后的编号是64&#xff0c;但是并不是有64个信号&#xff0c;没有32和33号信号&#xff0c;也就是说&#xff0c;一共有62个信号&#xff0c;前31个信号是标准信号&#xff08;非实时信号&#xff09;&#xff0c;后31个信号是实时…

Android自定义view;实现掌阅打开书籍动画效果

这里利用自定义view的方式来处理&#xff0c;初始化数据&#xff0c;camera通过setLocation调整相机的位置&#xff0c;但是Camera 的位置单位是英寸&#xff0c;英寸和像素的换算单位在 Skia 中被写成了72 像素&#xff0c;8 x 72 576&#xff0c;所以它的默认位置是 (0, 0, …

Linux基础篇:Linux网络yum源——以配置阿里云yum源为例

Linux网络yum源——以阿里云为例 一、网络yum源介绍 Linux中的YUM&#xff08;Yellowdog Updater, Modified&#xff09;源是一个软件包管理器&#xff0c;它可以自动处理依赖关系并安装、更新、卸载软件包。YUM源是一个包含软件包的远程仓库&#xff0c;它可以让用户轻松地安…

用户账号和组账号及管理

用户账号和组账号 Linux中每个用户是通过 User Id &#xff08;UID&#xff09;来唯一标识的 新建用户 1-60000 自动分配 0-65535 端口号&#xff0c;系统是靠uid来区分用户身份的&#xff0c;用户的uid 为0 就是超级管理员 1.用户账号的类型 超级管理员:权限最高的用户,roo…

Flutter Web 的未来,Wasm Native 即将到来

早在去年 Google I/O 发布 Flutter 3.10 的时候就提到过&#xff0c; Flutter Web 的未来会是 Wasm Native &#xff0c;当时 Flutter 团队就表示&#xff0c;Flutter Web 的定位不是设计为通用 Web 的框架&#xff0c;类似的 Web 框架现在有很多&#xff0c;而 Flutter 的定位…

[lesson06]内联函数分析

内联函数分析 常量与宏回顾 C中的const常量可以替代宏常数定义&#xff0c;如&#xff1a; C中是否有解决方案替代宏代码片段&#xff1f; 内联函数 C中推荐使用内联函数替代宏代码片段 C中使用inline关键字声明内联函数 内联函数声明时inline关键字必须和函数定义结合在…

营销中的归因人工智能

Attribution AI in marketing 归因人工智能作为智能服务的一部分&#xff0c;是一种多渠道算法归因服务&#xff0c;根据特定结果计算客户互动的影响和增量影响。有了归因人工智能&#xff0c;营销人员可以通过了解每个客户互动对客户旅程每个阶段的影响来衡量和优化营销和广告…

深入理解计算机系统 家庭作业 2.83

要读懂题目挺难的 A. 假设我们要求的无穷串是x0.yyyyyyy... Y(0.y<<ky) (由YB2Uk(y)得到,B2Uk是一个截断成k位的函数) x0.yyyyy...(这是我们假设的) 于是有 Yx y.yyyyyy... Yx y.yyyyyy... x<<k Yx-x xY(-1) B. a.Y5 k3 ,x5/7 b.Y6 k4 ,x6/152/5 c…

JavaScript权威指南(第7版) 笔记 - 扩展操作符总结

扩展操作符 ... &#xff0c;不是真正意义上的JavaScript操作符。 let str "0123ABC" console.log(typeof ...str);// Uncaught SyntaxError: Unexpected token ... 上面的第2行代码会报错&#xff0c;… 操作符只能在数组字面量、对象字面量、函数调用中使用。 在…

python-基础篇-字符串、列表、元祖、字典-字符串

文章目录 2.3字符串、列表、元祖、字典2.3.1字符串2.3.1.1字符串介绍2.3.1.1.1python中字符串的格式&#xff1a;2.3.1.1.2字符串在内存中的存储方式 2.3.1.2字符串的输入输出2.3.1.2.1字符串输出2.3.1.2.2字符串输入2.3.1.2.3组字符串的方式 2.3.1.3下标和切片2.3.1.3.1下标索…

vscode 连接远程服务器 服务器无法上网 离线配置

离线配置 vscode 连接远程服务器 .vscode-server 1. .vscode-server下载 使用vscode连接远程服务器时会自动下载配置.vscode-server文件夹&#xff0c;如果远程服务器无法联网&#xff0c;则需要手动下载 1&#xff09;网址&#xff1a;https://update.code.visualstudio.com…

AttributeError: ‘Text‘ object has no property ‘FontSize‘

在学习《机器学习理论与实践》——1 机器学习编程语言基础中&#xff0c;使用Matplotlib画图&#xff08;在坐标轴或绘图区显示中文&#xff09;时&#xff0c;产生AttributeError: Text object has no property FontSize 错误解决。 AttributeError: Text object has no prop…

响应跨域的两种方式

第一种&#xff1a; Configuration public class CorsConfication {Beanpublic CorsWebFilter corsWebFilter() {UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration new CorsConfiguration();//1、配置跨…

【随笔】Git 高级篇 -- 整理提交记录(上)(十五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…