当前位置: 首页 > news >正文

stack和queue的使用和模拟实现

文章目录

  • 前言
  • 一、stack的介绍和使用
    • 1.1 stack的介绍
    • 1.2 stack的使用
    • 1.3 stack的模拟实现
  • 二、queue的介绍和使用
    • 2.1 queue的介绍
    • 2.2 queue的使用
    • 2.3 queue的模拟实现
  • 三、容器适配器
    • 4.1 什么是适配器
    • 4.3 deque的简单介绍(了解)
  • 四、为什么选择deque作为stack和queue的底层默认容器


前言

上次写博客距今天已有20天了,暑假的休息到今天也就结束了,相信很多朋友和我一样虽然开学了,但还在家里上网课中,然后今天我来给大家聊聊关于C++中的stack和queue的知识,还有关于deque的了解知识。
还有给大家一个建议,C++中的容器建议根据文档来去学习,很多东西脑子是记不住的,附上C++的文档如下
C++文档
在这里插入图片描述
打开后建议进入旧的版本,比较容易找到我们需要的东西
在这里插入图片描述
在方框中搜索即可


正文开始

一、stack的介绍和使用

1.1 stack的介绍

stack文档介绍
在这里插入图片描述

1.stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定
的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。
2.stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类
3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类

在这里插入图片描述

1.2 stack的使用

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

1.3 stack的模拟实现

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

namespace hulu
{
	//template<class T,class Container= vector<T>>
	//template<class T, class Container = list<T>>
	template<class T, class Container = deque<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		T top()
		{
			return _con.back();
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

因为容器适配器中选用的是内置类型vector,所以不用对stack进行初始化和构造函数的实现,由编译器帮你实现.

二、queue的介绍和使用

2.1 queue的介绍

queue的文档介绍

在这里插入图片描述

  1. 队列是一种容器适配器,专门用于先进先出中操作,其中从容器一端插入元素,另一端获取元素。
  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()将队头元素出队列

2.3 queue的模拟实现

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

namespace hulu
{
	//list
	template<class T, class Container = list<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_front();
		}
		T front()
		{
			return _con.front();
		}
		T back()
		{
			return _con.back();
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

三、容器适配器

4.1 什么是适配器

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

我们先来看看库里对stack和queue容器适配器的实现是用什么来完成的

![在这里插入图片描述](https://img-blog.csdnimg.cn/17c0144b151149be8cbd5c28f046b503.png
可以看出库里对栈和队列的实现利用到了deque,deque是一个双端队列

4.3 deque的简单介绍(了解)

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

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

四、为什么选择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不需要遍历,所以本身也就没有迭代器,只需要在容器的一端或者两端操作数即可
2.stack和deque的元素增长中可能需要扩容,但是deque不需要,容量满了,继续开辟一小段空间就好
结合了deque的优点,而完美的避开了其缺陷。


(本章完)

相关文章:

  • 【C++】 string类常用接口的实现
  • 华为防火墙基础自学系列 | 汇总
  • TNet 中 JoinChannel 场景名可写可不写
  • 使用容器编译Yocto镜像
  • 【uniapp】小程序中修改Vant组件navbar左箭头的颜色及图标
  • 【区块链 | 智能合约】如何编写一个可升级的智能合约
  • java毕业设计开题报告javaweb户籍管理系统|户口
  • 交换机堆叠+链路聚合+浮动静态路由
  • (分布式缓存)Redis持久化
  • 计算机组成原理第二章----数据信息的表示 详解版(写的这么接地气我一下就懂了?)
  • windows 常用命令字典
  • 【案例回顾】春节一次较波折的MySQL调优
  • IDEA2020创建JavaSE项目改造成JavaWeb项目并配置tomcat
  • 分布式任务调度Schedulerx2.0工作原理
  • ATF启动(三):BL2
  • @angular/forms 源码解析之双向绑定
  • 30秒的PHP代码片段(1)数组 - Array
  • CEF与代理
  • create-react-app做的留言板
  • Git学习与使用心得(1)—— 初始化
  • HTTP请求重发
  • IDEA常用插件整理
  • JavaScript 一些 DOM 的知识点
  • Java比较器对数组,集合排序
  • Java新版本的开发已正式进入轨道,版本号18.3
  • laravel 用artisan创建自己的模板
  • nginx 负载服务器优化
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • vue-loader 源码解析系列之 selector
  • 从重复到重用
  • 二维平面内的碰撞检测【一】
  • 回顾2016
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 免费小说阅读小程序
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 软件开发学习的5大技巧,你知道吗?
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 详解移动APP与web APP的区别
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 在Mac OS X上安装 Ruby运行环境
  • 2017年360最后一道编程题
  • ​【已解决】npm install​卡主不动的情况
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (2020)Java后端开发----(面试题和笔试题)
  • (52)只出现一次的数字III
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (day6) 319. 灯泡开关
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (笔试题)合法字符串
  • (二)fiber的基本认识
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)计算机毕业设计SSM基于健身房管理系统