初识C++ · 模拟实现stack和Queue

目录

前言:

1 Stack

1.1 双端队列

2 Queue


前言:

经历了list三个自定义类型的洗礼,来个简单的放松放松,即栈和队列:

文档记录的,栈和队列是一种容器适配器,它们不属于stl,但是它们的大体结构我们都是了解的,在数据结构初阶我们已经用了C语言进行实现,这里用C++进行实现。


1 Stack

根据文档,stack也是使用了模板,第一个参数是数据类型,那么第二个是?

我们在C语言阶段使用的是一个整型指针,一个size一个capacity来实现,如果我们在C++仍然这样实现就不用介绍了,没意思了就。

后面的参数deque是另一种结构,叫做双端队列,后面细说,为什么引入第二个模板参数呢?

因为我们有了vector list基础,完全可以复用的,为什么复用vector list,就和deque有关了。

1.1 双端队列

deque是双端队列,那么为什么在stack queue的模板参数里面都有这个结构呢?

因为这个结构集成了vector和list,但是不是只集成了它们的优点。


先简单谈谈deque的结构

list的优点是插入删除效率很高,缺点是不好访问数据,vector的优点是访问任意数据的效率很高,缺点是插入删除数据如果在头部或者中间的效率很低。

所以惠普的大佬就寻思再来一个结构,可以当vector用也可以当list使用,这里因为是了解,所以就直接给结构了:

 看起来就像是个大boss,当我们存数据的时候,该结构会开一块空间,比如叫buff,空间大小为16,当一直插入数据,该数据插满之后,不会扩容,会重新开一块空间,空间大小也是16,数据插好后,我们该如何快速访问呢?
假定开的空间大小不变,我们想访问第i个数据,一块空间的大小为N,那么我们就应该先找到i数据在第几个空间的,在找该数据在第几个,找到在哪个空间可以i / N,第几个可以i % N,这样就可以快速访问了。

那么这么多空间应该如何管理?

这里使用的是中控指针,即再开一块空间,这块空间里面只有指针,指针指向不同的空间,但是指针是从中间开始存储的,因为涉及到头插。

但是对于deque的结构来说,只有两个迭代器,一个迭代器有4个指针,分别指向当前节点,头结果,尾节点和中控指针的节点,如果涉及到了插入删除数据,比如头插,就要先开一块空间,倒着存数据,那么此时找数据,i就要先减去这个不满的第一个数据块的数据个数,才能通过/ % 快速访问数据。中间插入数据的时候,有两个选择,一是重新开空间,二是在原来的空间上扩容,但是扩容之后,每个空间的大小不一样,找数据的效率就会降低了。

当涉及删除数据的时候,删除了之后,后面的数据往前移动,比较麻烦。

所以别看deque集成了list vector,缺点也蛮多的。

比如访问数据的效率不极致,中间插入删除数据也没list快,它就比较尴尬。。

这也是为什么,stack queue的模板参数默认是deque,这个"大哥"虽然有点缺点,但是用起来也算不错。


我们在stack实现的接口有入栈 出栈 size empty 返回栈顶元素,只有5个接口,这5个接口在vector里面都有,所以,直接使用:

namespace Free3
{
	template <class T, class container = vector<T>>
	class stack
	{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
		T& top()
		{
			return _con.back();
		}
		void pop()
		{
			_con.pop_back();
		}
	private:
		container _con;
	};

}

这里有个很牛逼的点就是,模板参数也可以有缺省值,我们给上vector<int>,那么默认的用vector来实现stack。

测试代码如下:

#include "Stack.h"
using namespace Free3;
int main()
{
	Free3::stack<int, vector<int>> s1;
	Free3::stack<int> s2;
	s1.push(1);
	s1.push(2);
	s1.push(3);
	s1.push(4);	
	s2.push(1);
	s2.push(2);
	s2.push(3);
	s2.push(4);
	s2.push(5);
	while (!s2.empty())
	{
		cout << s2.top() << " ";
		s2.pop();
	}
	cout << endl;
	return 0;
}

2 Queue

队列这里还有点不一样,栈可以用vector也可以用list,但是队列不行,队列的出队,相当于是头删,如果非要用vector里面的erase来头删也可以,但是效率很差,是O(N),这里就非常不推荐,所以队列就用list来实现。

namespace Free4
{
	template<class T>
	class Queue
	{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}
		void pop()
		{
			_con.pop_front();
		}
		size_t size()
		{
			return _con.size();
		}
		T& front()
		{
			return _con.front();
		}
		bool empty()
		{
			return _con.empty();
		}

	private:
		list<T> _con;
	};

}

感谢阅读!

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

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

相关文章

什么是云渲染?怎么使用呢?手把手教你

云渲染是一种利用云计算技术进行图形渲染的服务。它允许用户将渲染任务提交到云端服务器&#xff0c;由远程的计算机集群资源进行渲染操作&#xff0c;完成后再将渲染结果返回给用户。 云渲染技术的优势在于它可以提高渲染效率和质量&#xff0c;支持多任务同时加速渲染&#…

一个被无数人忽视的好项目

这个项目相信大家都在各大短视频平台见过&#xff0c;之前被我忽视了&#xff0c;当时的我自以为它是一时的热度&#xff0c;很快就会凉凉。但现在却生生被打脸了&#xff0c;这其实是非常好变现且流量也很大的一个好项目。 到底是什么好项目呢&#xff0c;没错&#xff0c;就…

[MYSQL]合作过至少三次的演员和导演

ActorDirector 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | actor_id | int | | director_id | int | | timestamp | int | ---------------------- timestamp 是这张表的主键(具有唯一值的列).编写解决方案…

黑马程序员——Spring框架——day04——SpringMVC基础

目录&#xff1a; SpringMVC简介 背景SpringMVC概述技术体系定位快速入门 目的需求步骤代码实操测试工具 PostMan简介PostMan安装PostMan使用知识点总结请求与参数处理 请求路径 环境准备问题分析解决方式请求方式 环境准备技术分析参数 基本数据类型POJO嵌套POJO数组集合&…

基于卷积神经网络(CNN)的深度迁移学习在声发射(AE)监测螺栓连接状况的应用

螺栓结构在工业中用于组装部件&#xff0c;它们在多种机械系统中扮演着关键角色。确保这些连接结构的健康状态对于航空航天、汽车和建筑等各个行业至关重要&#xff0c;因为螺栓连接的故障可能导致重大的安全风险、经济损失、性能下降和监管合规问题。 在早期阶段检测到螺栓松动…

四、利用启发式算法进行特定数据集的残差网络结构搜索【框架+源码】

背景&#xff1a;工作之后干的事情跟算法关联甚少&#xff0c;整理下读书期间的负责和参与的work&#xff0c;再熟悉学习下。 边熟悉边整理喽~ CV Tradictional workCV AI based work机械臂视觉抓取项目机器学习全流程 Pipeline训练平台OCR生产线喷码识别三维重建(SfM)ROS机器人…

springboot项目通过jar包部署到服务器

1. 将springboot项目打包成jar包 方式一&#xff1a;IDEA为例 出现 BUILD SUCCESS 证明打包成功&#xff0c;自动生成了 target 目录&#xff0c; jar 包就在目录里边 方式二&#xff1a;命令行&#xff08;得配置好maven环境变量&#xff09; 切换到项目目录下&#xff0c;…

springboot管理的各依赖版本查看

找一个springboot相关的依赖&#xff0c;比如这里我找mybatis 鼠标点击artifactId名称&#xff0c;图中蓝色字段&#xff0c;跳转到springboot依赖&#xff08;鼠标悬停在上面变成蓝色表示可点击跳转&#xff09;&#xff0c; 点击spring-boot-dependencites&#xff0c;跳转到…

基于FPGA的SystemVerilog练习

文章目录 一、认识SystemVerilogSystemVerilog的语言特性SystemVerilog的应用领域SystemVerilog的优势SystemVerilog的未来发展方向 二、流水灯代码流水灯部分testbench仿真文件 三、用systemVerilog实现超声波测距计时器测距部分led部分数码管部分采样部分顶层文件引脚绑定效果…

QT入门知识回顾

1 QT简介 1.1 Qt模块: Qt Core模块: 是QT类库的核心&#xff0c;所有其他模块都依赖这个模块 Qt Gui模块: 提供GUI程序的基本功能 Qt Network模块:提供跨平台的网络功能 Qt Widgets模块:提供创建用户界面的功能 1.2Qt的signal/slot机制 任何一个类只要类体前部书写 Q_OBJ…

TH方程学习 (6)

一、内容介绍 本节旨在使用优化算法的方法&#xff0c;旨在利用最小的燃耗实现目标的交会&#xff0c;变量为目标的转移时间。整个问题描述为&#xff1a; 本节拟采取粒子群优化的算法&#xff0c;matlab中自带的粒子群函数为particleswarm&#xff0c;其用法不详细介绍&#…

LeetCode:环形链表II

文章收录于LeetCode专栏 LeetCode地址 环形链表II 题目 给定一个链表&#xff0c;返回链表开始入环的第一个节点。如果链表无环&#xff0c;则返回null。   为了表示给定链表中的环&#xff0c;我们使用整数pos来表示链表尾连接到链表中的位置&#xff08;索引从0开始&#…

C++青少年简明教程:数组

C青少年简明教程&#xff1a;数组 C数组是一种存储固定大小连续元素的数据结构。数组中的每个元素都有一个索引&#xff0c;通过索引可以访问或修改数组中的元素。 在C中&#xff0c;数组中的元素数据类型必须一致。数组是一个连续的内存区域&#xff0c;用于存储相同类型的元…

std::shared_ptr,reset()函数

感慨&#xff1a;不深入阅读源代码&#xff0c;真的心虚&#xff0c;也用不好。 上代码&#xff1a; class A01 { public://std::weak_ptr<B0> b_ptr;int data{ 1234 };~A01() {std::cout << "A01 deleted\n";}void Print() { std::cout << &quo…

C++进阶:C++11

C11简介 在 2003 年 C 标准委员会曾经提交了一份技术勘误表 ( 简称 TC1) &#xff0c;使得 C03 这个名字已经取代了 C98 称为 C11 之前的最新 C 标准名称。不过由于 C03(TC1) 主要是对 C98 标准中的漏洞 进行修复&#xff0c;语言的核心部分则没有改动&#xff0c;因此人们习…

初始操作系统

概念&#xff1a; 1.系统资源的管理者&#xff1a;实质控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机地工作和资源的分配 2.向上层提供方便易用的服务&#xff1a;以提供给用户和其他软件方便接口和环境 封装思想&#xff1a;操作系统把一些丑…

小熊家务帮day10- 门户管理

门户管理 1 门户介绍1.1 介绍1.2 常用技术方案 2 缓存技术方案2.1 需求分析2.1.1 C端用户界面原型2.1.2 缓存需求2.1.3 使用的工具 2.2 项目基础使用2.2.1 项目集成SpringCache2.2.2 测试Cacheable需求Service测试 2.1.3 缓存管理器&#xff08;设置过期时间&#xff09;2.1.4 …

React@16.x(17)Portals

目录 1&#xff0c;使用2&#xff0c;事件冒泡 一句话总结&#xff1a;和 Vue3 的 Teleport 一个效果。 1&#xff0c;使用 import React, { PureComponent } from "react"; import ReactDOM from "react-dom";// 返回一个 React 元素&#xff08;ReactNo…

【Go语言精进之路】构建高效Go程序:零值可用、使用复合字面值作为初值构造器

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、深入理解并利用零值提升代码质量1.1 深入Go类型零值原理1.2 零值可用性的实践与优势1.2.1 切片(Slice)的零值与动态扩展1.2.2 Map的零值与安全访问1.2.3 函数参数与零值 二、使用复合字面值作为初值构造器2.1 结构体…

十分钟快速搭建检索、排序的大模型RAG系统

以上为实现效果 RAG是目前最火的大模型应用之一&#xff0c;如何能快速实现一个不错的demo呢&#xff1f; 参考 https://github.com/LongxingTan/open-retrievalshttps://colab.research.google.com/drive/1fJC-8er-a4NRkdJkwWr4On7lGt9rAO4P?uspsharing#scrollTo2Hrfp96UY…