C++stack和queue的模拟实现

1.stack的模拟实现

在这一部分嘞,我们不再用传统的模拟实现来实现今天要实现的内容,我们使用一种设计模式来实现今天的内容

设计模式

目前接触到的设计模式一共有两种:一种是适配器模式,一种是迭代器模式

迭代器设计模式

迭代器大家都熟悉,在string,vector,list中算是老朋友了,它为我们访问容器提供了一种统一的方式,在知道迭代器这种东西之前,我们访问数据,肯定是要知道该容器的结构细节才能访问的,比如,对于顺序表,你要知道它的底层是数组你才知道如何访问它的数据,对于链表,你要知道它的底层是一个一个的节点,你才知道要如何去访问它的数据,然而,迭代器的出现,为我们访问数据提供了一种统一的方式,它屏蔽了底层的细节

适配器设计模式

适配器大家生活中比较常见的就是电源适配器器,它的作用就相当于变压器,在不同的电压下都能够保证你的手机能够充上电,如果说迭代器的思想是封装的话,那么适配器的话就是转换,那么,让我们来看看,适配器在这一部分的应用

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

stack的模拟实现代码

#include<iostream>
#include<deque>
//
using namespace std;

//设计模式-适配器模式-主要是封装转换

namespace bit
{
	template<class T,class Container=deque<T>>
	class stack
	{
	public:
		void push_back(T x)
		{
			_con.push_back(x);
		}

		T& top()
		{
			return _con[_con.size()-1];
		}

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

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

		size_t size()
		{
			return _con.size();
		}
		
	private:
		Container _con;
	};

	void test_stack01()
	{
		stack<int> s;
		s.push_back(1);
		s.push_back(2);
		s.push_back(3);
		s.push_back(4);
		cout << s.size() << endl;
		while (!s.empty())
		{
			cout << s.top() << " ";
			s.pop();
		}
		cout << endl;
		
		
	}

}

上面用一个deque容器实现了一个stack,当让,这里也可以用其他的容器,比如,vector,list来实现,容器选择不唯一,这就是适配器模式,用别的容器来实现你想要的容器,肯定有人会好奇,deque是什么,那下面,我们就来介绍一下

deque

deque是我们得双向队列,什么意思嘞

从它得成员函数来看,它实现了头尾元素的插入删除,功能上是有点向vector和list的结合体,

我们知道vector的优点是:下标访问效率高

                            缺点是:头部插入删除需要挪动数据,效率非常低

                             list优点:任意位置插入删除只需要改变指针的指向,效率高

                                   缺点:下标访问效率低

而deque刚好就结合了它们两个的优点:下标访问效率还可以,头部插入删除效率也高,那我们来看一下它的初略结构

deque的大致结构

deque的结构就是这样一个一个的bufer的数组,每个数组可以存储一定量的个数,当想要尾插数据的时候,如果数据个数达到容量的时候,就会在后面再插入一个数组,如果想要头插一个,就再前面再多插入一个数组

那它的下标访问是如何进行的,请看下图:

但是,deque的也是有缺点的

 再上面的程序中,vector和deque中都有一定量的数据,对里面的数据进行排序,再计算两者排序需要用的时间,发现deque要用到的时间高出vector很多

那我们再来看一下下一个程序

再这个程序里面嘞,我们是把deque里面的数据拷贝到vecror里面,等到vector里面的数据排序完了,再把vector的数据放回deque里面 ,发现deque的排序时间、依然然高出后者的很多

那到这里我们就做一个总结:

deque的真实结构

 首先,有两个迭代器,start迭代器指向第一个元素,finsh的迭代器指向最后一个元素的下一个位置

这里的operator*操作,就是取当前cur指向的元素

 

这里的operator++就是,当cur走到了当前数组的last位置,就该迭代器就就指向下一个node,也就是下一个数组 

还有就是头插

 

queue的模拟实现

#include<iostream>
#include<queue>
#include<deque>
using namespace std;

namespace bit
{
	template<class T,class Container=deque<T>>
	class queue
	{
	public:
		void push_back(T x)
		{
			_con.push_back(x);
		}

		T& top()
		{
			return _con[0];
		}

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

		bool empty()
		{
			return _con.empty();
		}
		
		size_t&size()
		{
			return _con.size();
		}



	private:
		Container _con;
	};

	void test_queue01()
	{
		queue<int> q;
		q.push_back(10);
		q.push_back(20);
		q.push_back(30);
		q.push_back(40);
		while (!q.empty())
		{
			cout << q.top()<<" ";
			q.pop();
		}
		cout << endl;

	}
}

为什么使用deque作为默认容器

tack是一种后进先出的特殊线性数据结构,因此只要具有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/902286.html

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

相关文章

linux内核的原子操作与用户态的原子操作差别

Linux内核的原子操作与用户态的C语言原子操作主要在以下几个方面存在区别&#xff1a; 实现层级&#xff1a; 内核原子操作&#xff1a; 直接依赖于硬件提供的原子指令&#xff08;如CAS、原子加等&#xff09;&#xff0c;通过内核提供的函数&#xff08;如atomic_add()、at…

多目标优化求解的内涵主要方法

多目标优化问题 定义如下多目标优化问题&#xff1a; min ⁡ f ( x ) [ f 1 ( x ) , f 2 ( x ) , ⋯ , f n ( x ) ] ( 1 ) \min\quad f(x)[f_1(x),f_2(x),\cdots,f_n(x)]\quad(1) minf(x)[f1​(x),f2​(x),⋯,fn​(x)](1) 其中&#xff0c; f i ( x ) , ∀ i 1 , ⋯ , n f_…

TS中forEach与map,filter的简单事例及简单的说明

1、先上一张效果图&#xff1a; 2、再上一个代码&#xff1a; <template><div><h1>Array Test</h1><ul><li v-for"item in items" :key"item.id">{{ item.name }}</li></ul><div style"display:…

攻防世界的新手web题解

攻防世界引导模式 1、disabled_button 好&#xff0c;给了一个按钮&#xff0c;第一道题目就不会做 看的wp<input disabled class"btn btn-default" style"height:50px;width:200px;" type"submit" value"flag" name"auth&q…

嵌入式软开——八股文——学习引导和资料网址

1、找工作期间整理的相关八股资料&#xff0c;可以帮助初学者按此流程快速学习入门&#xff0c;帮助有基础的同学快速复习、查缺补漏&#xff0c;帮助找工作面试的同学&#xff0c;快速复习知识点。 2、前13个文件夹为单独模块的相关学习内容&#xff0c;里面涵盖相关模块的主…

【C++复习】第二弹-内存管理

目录 前言 1.结合地址空间来理解不同对象的存储区域 2.malloc和free以及new和delete的区别 3.什么是内存泄漏&#xff1f; 前言 对于一个程序来说&#xff0c;我们必须知道他的各个位置的变量存放在哪里的&#xff0c;所以我们必须要清楚C的内存分布。其实内存管理是衡量一个…

使用Python计算相对强弱指数(RSI)进阶

使用Python计算相对强弱指数&#xff08;RSI&#xff09;进阶 废话不多说&#xff0c;直接上主题&#xff1a;> 代码实现 以下是实现RSI计算的完整代码&#xff1a; # 创建一个DataFramedata {DATE: date_list, # 日期CLOSE: close_px_list, # 收盘价格 }df pd.DataF…

CodeQL学习笔记(1)-QL语法(逻辑连接词、量词、聚合词、谓词和类)

最近在学习CodeQL&#xff0c;对于CodeQL就不介绍了&#xff0c;目前网上一搜一大把。本系列是学习CodeQL的个人学习笔记&#xff0c;根据个人知识库笔记修改整理而来的&#xff0c;分享出来共同学习。个人觉得QL的语法比较反人类&#xff0c;至少与目前主流的这些OOP语言相比&…

小白投资理财 - 看懂 K 线形态下

小白投资理财 - 看懂 K 线形态下 熊势吞噬牛势吞噬孕育线牛市孕育线熊市孕育线 早晨之星黄昏之星总结 前一篇《 小白投资理财 - 看懂 K 线形态上》介绍了 6 种 K 线形态&#xff0c;有天气预报的&#xff0c;又有灭霸&#xff0c;小叮当&#xff0c;今天介绍另外 6 种在股市上…

认识CSS语法

CSS&#xff08;网页美容&#xff09; 重点&#xff1a;选择器、盒子模型、浮动、定位、动画&#xff0c;伸缩布局 Css的作用&#xff1a; 美化网页&#xff1a;CSS控制标签的样式 网页布局&#xff1a;CSS控制标签的位置 概念&#xff1a;层叠样式表&#xff08;级联样式表…

Linux | Rsync 命令:16 个实际示例(下)

引言 Rsync&#xff08;远程同步&#xff09;是Linux/Unix系统中用于远程和本地复制及同步文件和目录的常用工具。 利用rsync命令&#xff0c;您可以轻松地在不同目录、硬盘和网络之间进行数据的远程和本地复制与同步&#xff0c;进行数据备份&#xff0c;以及在两台Linux系统间…

【正点原子K210连载】第四十八章 自学习分类实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第四十八章 自学习分类实验 在上一章节中&#xff0c;介绍了利用maix.KPU模块实现了MNIST的手写数据识别&#xff0c;本章将继续介绍利用maix.KPU模块实现的自学习分类。通过本章的学习&#xff0c;读者将学习到自学习分类应用在CanMV上的实现。 本章分为如下几个小节&#xf…

维乐Senso Edge坐垫,自然并不远,向往就前往

嘿&#xff0c;是不是已经厌倦了城市的钢筋森林&#xff0c;渴望一场说走就走的自然之旅&#xff1f;别急&#xff0c;维乐Senso Edge坐垫带你飞&#xff0c;让我们的车轮一起碾过每一寸向往的土地&#xff01;    追逐风&#xff0c;拥抱自然。你还记得第一次骑行时的那份…

【功能安全】 独立于环境的安全要素SEooC

目录 01 SEooC定义 02 SEooC开发步骤 03 SEooC开发示例 04 SEooC问答 01 SEooC定义 缩写: SEooC:Safety Element out of Context独立于环境的安全要素 SEooC出处:GB/T34590.10—2022,第9章节 SEooC与相关项什么关系? SEooC可以是系统、系统组合、子系统、软件组件、…

Linux 系统中,将网络配置从 DHCP 改为静态 IP的几种方法

Linux 系统中&#xff0c;将网络配置从 DHCP 改为静态 IP 可以通过几种不同的方法来实现&#xff0c;下面是几种常见的方式&#xff1a; 方法一&#xff1a;使用 connman&#xff08;Connection Manager&#xff09; 如果你已经在使用 connman 管理网络&#xff0c;可以通过修…

MATLAB实现遗传算法优化零件拆卸装配问题

零件拆卸装配问题是一个有复杂约束的优化问题&#xff0c;它涉及到零件之间的连接关系、拆卸或装配的顺序、工具的使用、操作成本。 1.假设&#xff1a; &#xff08;1&#xff09;零件完整性&#xff1a;每个零件在拆卸和装配过程中保持完整&#xff0c;不发生形变或损坏 &…

MATLAB生物细胞瞬态滞后随机建模定量分析

&#x1f3af;要点 基于随机动态行为受化学主方程控制&#xff0c;定量分析单细胞瞬态效应。确定性常微分方程描述双稳态和滞后现象。通过随机性偏微分方程描述出暂时性滞后会逐渐达到平稳状态&#xff0c;并利用熵方法或截断方法计算平衡收敛速度的估计值。随机定量分析模型使…

软考中级嵌入式系统设计师笔记分享(二)

1.TTL 电路是电流控制器件&#xff0c;而CMOS 电路是电压控制器件。 2.TTL 电路的速度快&#xff0c;传输延迟时间短(5-10ns)&#xff0c;但是功耗大。 常见的串行总线有 SPI、II2C、USB、RS232/RS422/RS485、CAN等;高速串行总线主要有 SATA、PCIE、IEEE 1394、Rapidl0、USB 3…

鸿蒙UI开发——基于全屏方案实现沉浸式界面

1、概 述 典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。 其中状态栏和导航条&#xff0c;通常在沉浸式布局下称为避让区&#xff0c;避让区之外的区域称为安全区。 开发应用沉浸式效果主要指&#xff1a;通过调整状态栏、应用界面和导航条的显示效果来减少状态…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-21目录1. The Fair Language Model Paradox摘要研究背景问题与挑战如何解决创新点算法模型实验效果重要数据与结论推荐阅读指数&…