C++:deque的概念以及stack和queue的模拟实现

news2024/11/17 23:26:56

文章目录

  • stack的模拟实现
  • deque
  • queue的模拟实现

本篇主要总结的是stackqueue的模拟实现以及deque的原理

stack的模拟实现

和前面的模拟实现相同,首先要看官方实现的功能

在这里插入图片描述

在这里插入图片描述

这里引入了Container的概念,从字面意思来看,也就是说,在实例化模板的时候实际上是需要实例化两个参数的,一个是栈内元素的数据类型,一个是容器的类型,这里通过缺省参数给定了一个deque,因此平时使用的时候不需要实例化第二个参数,关于deque的概念后面再进行讲解

从中可以看出,stack的实现是以一个容器为模板,在这个模板的基础上引申出了栈的概念,因此在模拟实现的过程中相对容易一些

#include <iostream>
#include <vector>
#include <list>
#include <deque>

namespace mystack
{
	template <class T,class Container>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		bool empty()
		{
			return _con.empty();
		}
		int size()
		{
			return _con.size();
		}
		const T& top()
		{
			return _con.back();
		}
	private:
		Container _con;
	};
}

但是在实际的栈的实现中,是使用带有缺省参数的模板参数,在容器的实现中是使用的是deque,因此在使用STL中的模板实例化只需要实例化第一个参数即可,默认是使用的是deque,也可以实例化为vectorlist

#include "stack.h"
#include <stack>


// 采用vector来当容器生成栈
int main()
{
	std::stack<int, std::vector<int>> s;

	// 入栈
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);

	// 出栈
	while (!s.empty())
	{
		std::cout << s.top() << " ";
		s.pop();
	}

	return 0;
}
#include "stack.h"
#include <stack>


// 采用list来当容器生成栈
int main()
{
	std::stack<int, std::list<int>> s;

	// 入栈
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);

	// 出栈
	while (!s.empty())
	{
		std::cout << s.top() << " ";
		s.pop();
	}

	return 0;
}

deque

那么下面引入deque的概念,什么是deque,它的用法又是什么?

还是从cplusplus中查阅它的概念

deque的概念

deque也被叫做双端队列,从名字可以看出通俗来说它就是在两端都可以进出的队列,因此可以随意的头插头删尾插尾删

在这里插入图片描述

deque的底层实现方式

从上面的内容可以知道,deque可以实现在容器两端进行插入删除的操作,那其内部是如何进行工作的?

在这里插入图片描述
上面是两个容器的不同点,其实可以看出vector的优点其实就对应的是list的缺点,而list的优点就对应了vector的缺点,因此才需要根据不同的实验需求选择对应的容器来使用

deque的原理

在这里插入图片描述
deque的原理就是采用了一个中控数组用来管理每一个小数组,所以中控数组是一个指针数组,其中存储的是每一个小数组的指针,当需要插入元素的时候,就在这个中控数组的中间部分的指针指向的元素中进行插入,这样的模式就导致它具备了向前面插入数据,也具备了向后面插入数据的能力

向头部和尾部插入数据:

在这里插入图片描述


如果头部有数据继续头插,那么就会开辟额外的小数组用来存储

在这里插入图片描述
但是这样就产生了一个问题,如果中控数组控制的小数组已经排满了数据,但是我还要实施插入的操作应该如何实现?

  1. 可以整体挪动数据,把所有数组向后挪动一位
  2. 可以对单个小数组进行扩容,使得每一个小数组的长度不一样

这是两种扩容的思路,如果采用第一种思路,那么在挪动数据的时候效率会很低,但是优势是进行下标的随机访问的时候拥有更高效的功能
如果采用的是第二种思路,那么在插入数据的时候成本很低,但是在访问的时候就有较高的计算成本

因此两种扩容思路都有其好的一点和坏的一点,具体如何实施看对于容器的需求如何

在实际的使用场景中,对于deque其实是不常用的,因为它兼容了vectorlist的部分优势,但是在随机访问的情况下不如vector,在插入删除数据的方面不如list,只是出于一个较为兼容的容器,在实际开发中应用场景并不多

在这里插入图片描述

那为什么会选择deque作为底层容器的实现?

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()pop_back()操作的线性结构,都可以作为stack的底层容器,比如vectorlist都可以; queue是先进先出的特殊线性数据结构,只要具有push_back()pop_front()操作的线性结构,都可以作为queue的底层容器,比如list

但是STL中对stackqueue默认选择deque作为其底层容器,主要是因为:

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

queue的模拟实现

#include <iostream>
#include <vector>
#include <list>
#include <deque>

namespace myqueue
{
	template <class T,class Container=std::deque<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_front();
		}
		bool empty()
		{
			return _con.empty();
		}
		int size()
		{
			return _con.size();
		}
		const T& front()
		{
			return _con.front();
		}
		const T& back()
		{
			return _con.back();
		}
	private:
		Container _con;
	};
}
#include "queue.h"

int main()
{
	myqueue::queue<int> q;

	// 插入数据
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);

	// 打印数据
	while (!q.empty())
	{
		std::cout << q.front() << " ";
		q.pop();
	}

	return 0;
}

这里直接使用了deque作为缺省参数,因此实例化只需要使用一个参数即可

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

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

相关文章

pdf转换成word,这里有几个不错的方法

pdf转换成word怎么转&#xff1f;大家都知道&#xff0c;在电脑进行各种文件格式转换中&#xff0c;PDF转换为Word文档的需求量应该是最大的。在我们的日常工作中&#xff0c;经常需要将PDF转换为Word格式。为什么要将pdf文件转换成word&#xff0c;相信大家也都应该知道的&…

图解 | 这就是网络

你是一台电脑&#xff0c;你的名字叫 A 很久很久之前&#xff0c;你不与任何其他电脑相连接&#xff0c;孤苦伶仃。 直到有一天&#xff0c;你希望与另一台电脑 B 建立通信&#xff0c;于是你们各开了一个网口&#xff0c;用一根网线连接了起来。 用一根网线连接起来怎么就能&q…

二叉树链式结构基础

一、前中后序遍历 1、前序遍历&#xff1a;前序遍历是采用 根 - 左子树 - 右子树 的顺序遍历二叉树。 也就是把整棵树分为一个个子问题&#xff0c;每个结点都可以看作 根、左子树、右子树 三个部分 (左右子树可以为空&#xff0c;就是单节点&#xff0c;根为空就表示探索完成&…

自动化测试需知的4项测试工具!

一般来说学自动化会建议大家先学selenium&#xff0c;因为最早的时候&#xff0c;自动化就代表selenium&#xff0c;进入测试行业就开始做接口测试&#xff0c;而且现在基本每个公司都需要接口测试。今天就和大家聊一下接口测试的工具。 一、Robot Framework 机器人框架。之所…

利用证书给pdf文件添加数字签名

文章目录 给pdf文件签名文件准备构建印章获取证书方法一 阿里云申请证书方法二 自建证书 利用证书给pdf签名在指定位置签名在指定坐标签名在指定签名域签名 给pdf文件签名 如何给pdf文件签名&#xff0c;这样pdf文件就具有不可修改性&#xff0c;具有鉴权、完整性、不可抵赖。…

【操作系统笔记】内存寻址

物理寻址 主存&#xff08;内存&#xff09; 计算机主存也可以称为物理内存&#xff0c;内存可以看成由若干个连续字节大小的单元组成的数组每个字节都有一个唯一的物理地址&#xff08;Physical Address&#xff09;CPU访问内存前&#xff0c;先拿到内存地址&#xff0c;然后…

通讯网关软件005——利用CommGate X2OPC实现OPC客户端访问MS SQL服务器

本文推荐利用CommGate X2OPC实现OPC客户端访问MS SQL服务器获取数据。CommGate X2OPC是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;上位机通过OPC Client软件来获取MS SQL数据库的数据。 …

Qt扩展-KDDockWidgets 简介及配置

Qt扩展-KDDockWidgets 简介及配置] 一、概述二、编译 KDDockWidgets 库1. Cmake Gui 中选择源文件和编译后的路径2. 点击Config&#xff0c;配置好编译器3. 点击Generate4. 在存放编译的文件夹输入如下命令开始编译 三、qmake 配置 一、概述 kdockwidgets是一个由KDAB组织编写…

基于GBDT+Tkinter+穷举法按排队时间预测最优路径的智能导航推荐系统——机器学习算法应用(含Python工程源码)+数据集(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境Pycharm 环境Scikit-learnt 模块实现1. 数据预处理2. 客流预测3. 百度地图API调用4. GUI界面设计1&#xff09;手绘地图导入2&#xff09;下拉菜单设计3&#xff09;复选框设计4&#xff09;最短路径结果输出界面…

睿趣科技:抖音开一家网店大概什么时候回本

随着移动互联网的迅猛发展&#xff0c;社交媒体平台如抖音成为了商家推广产品和服务的热门渠道之一。许多人都希望能够通过在抖音上宣传自己的产品&#xff0c;甚至考虑开一家网店&#xff0c;但回本的时间是一个关键问题。本文将探讨抖音开一家网店大概什么时候回本的问题。 首…

calloc

目录 前提须知&#xff1a; 函数介绍&#xff1a; 原型如下&#xff1a; 申请空间&#xff1a; 判断是否申请成功&#xff1a; 释放空间&#xff1a; calloc与malloc的相同之处与不同之处&#xff1a; 相同之处&#xff1a; 不同之处&#xff1a; 举例&#xff1a; ca…

API接口知识小结及电商数据平台商品详情接口请求案例

应用程序接口API&#xff08;Application Programming Interface&#xff09;&#xff0c;是提供特定业务输出能力、连接不同系统的一种约定。这里包括外部系统与提供服务的系统&#xff08;中后台系统&#xff09;或后台不同系统之间的交互点。包括外部接口、内部接口&#xf…

无涯教程-JavaScript - SUMXMY2函数

描述 SUMXMY2函数返回两个数组中相应值的差的平方和。 语法 SUMXMY2 (array_x, array_y)争论 Argument描述Required/OptionalArray_xThe first array or range of values.RequiredArray_yThe second array or range of values.Required Notes 参数应为数字或名称,数组或包…

Vite前端构建工具详解

Vite前端构建工具 Vite 是一款新兴的前端构建工具&#xff0c;它的出现带来了前端开发体验的革命性变化。本文将介绍 Vite 的基本概念和核心特性&#xff0c;并通过代码实例来演示其强大功能。 什么是 Vite&#xff1f; Vite 是由 Evan You&#xff08;Vue.js 的创始人&#x…

掌握进度管理基本指南,保证项目不延期

项目管理中的进度管理是规划、制定、控制和监控项目时间表的过程&#xff0c;确保任务和活动按时完成。 假设你是一名项目经理&#xff0c;带着团队组织一场备受瞩目的音乐节。精确的时间安排是关键。你需要确保演出者准时到达并按计划表演&#xff0c;所有供应商都准备就绪&a…

「干货」洁净室悬浮粒子计数器全部常见型号参数汇总

我们的人体工程学设计轻巧的Lighthouse手持式3016-IAQ是市场上先进的手持式粒子计数器&#xff0c;其质量浓度模式的密度约为μg/ m3。Lighthouse手持式粒子计数器最多可提供6个粒径同时计数的通道&#xff0c;可在快速&#xff0c;易于阅读的彩色触摸屏上显示累积和差分粒子计…

推荐一个可以采集众多国内外电商网站数据的工具

淘宝API 接入地址 item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论item_fee 获得淘宝商品快递费用item_password 获得淘口令真实urlitem_list_updown 批量获得淘宝商品上下架时间seller_info 获得淘宝店铺详情item_search 按关键…

做题杂记222

文章目录 题1题2题3题4 一些较简单的题目。里面有些小点&#xff0c;稍不留意跑起来也挺费时。 题1 leak 题目描述&#xff1a; #!/usr/bin/env python # -*- coding: utf-8 -*- from Crypto.Util.number import * from secret import FLAGm bytes_to_long(FLAG)def getpq(n…

新消费降温,良品铺子还能走多远?

如果时间倒退到多年前&#xff0c;杨红春应该不会料到现在良品铺子的境遇。 从2006年创立至今&#xff0c;前半段良品铺子经历了品牌升级&#xff0c;从线下发展到平台电商、社交电商&#xff0c;做APP客户端进行全渠道的营销&#xff0c;把一家曾入不敷出的小店&#xff0c;养…

echarts 轴文字内容太长导致显示不全解决方案

情况&#xff1a;Y轴内容是文字&#xff0c;内容太长可能会系那是不全。调整grid会导致短数据前的留白过于多。 解决方案&#xff1a; 方法一&#xff1a; 首先可以配置grid自适应 &#xff0c; containLabel 属性设置true &#xff08;这常用于『防止标签溢出』的场景&…