【C++】STL——stack和queue的模拟实现、空间适配器、deque的介绍、增删查改函数的简单实现

news2024/11/17 11:36:39

文章目录

  • 1.deque的简单介绍
  • 2.模拟实现stack
  • 3.模拟实现queue

1.deque的简单介绍

deque的介绍文档

在这里插入图片描述

  deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

在这里插入图片描述

deque的缺陷

  与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。

  与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

  但是,deque有一个致命缺陷:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下, 而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构

为什么选择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不仅效率高,而且内存使用率高。

2.模拟实现stack

在这里插入图片描述

在这里插入图片描述

  这个stack类模板是一个栈的实现,使用了一个名为Container的模板参数来指定底层容器的类型,默认为deque。也就是说,如果不指定底层容器类型,那么stack类将使用deque作为底层容器

  push:将元素x插入到栈顶,实际上是调用底层容器的push_back函数。

  pop:弹出栈顶元素,实际上是调用底层容器的pop_back函数。

  top:返回栈顶元素的引用,实际上是返回底层容器的最后一个元素的引用。

  size:返回栈中元素的个数,实际上是返回底层容器的size函数的返回值。

  empty:判断栈是否为空,实际上是调用底层容器的empty函数。

  这个stack类模板的目的是提供一个封装了底层容器的栈的实现,使得我们可以方便地使用栈的各种操作。底层容器的选择可以根据我们具体的需求进行自定义或者使用默认的deque容器。

#pragma once
#include<vector>
#include<list>
#include<deque>

namespace st
{
	//空间配置器
	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;
	};
}

3.模拟实现queue

在这里插入图片描述

  这个queue类模板是一个队列的实现,使用了一个名为Container的模板参数来指定底层容器的类型,默认为deque。也就是说,如果不指定底层容器类型,那么queue类将使用deque作为底层容器。

  push:将元素x插入到队列的末尾,实际上是调用底层容器的push_back函数。

  pop:弹出队列的第一个元素,实际上是调用底层容器的pop_front函数。

  front:返回队列的第一个元素的引用,实际上是返回底层容器的第一个元素的引用。

  back:返回队列的最后一个元素的引用,实际上是返回底层容器的最后一个元素的引用。

  size:返回队列中元素的个数,实际上是返回底层容器的size函数的返回值。

  empty:判断队列是否为空,实际上是调用底层容器的empty函数。

  这个queue类模板的目的是提供一个封装了底层容器的队列的实现,使得用户可以方便地使用队列的各种操作。底层容器的选择可以根据具体的需求进行自定义或者使用默认的deque容器。

#pragma once
#include<vector>
#include<list>
#include<deque>

namespace que
{
	//空间配置器
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{
			_con.pop_front();
			//_con.erase(_con.begin());
		}

		T& front()
		{
			return _con.front();
		}

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

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

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

	private:
		Container _con;
	};
}

测试代码

#define _CRT_SECURE_NO_WARNINGS 1

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

#include"stack.h"
#include"queue.h"

void test_stack()
{
	//st::stack<int, std::vector<int>> st1;
	st::stack<int> st1;
	st1.push(1);
	st1.push(2);
	st1.push(3);
	st1.push(4);

	while (!st1.empty())
	{
		cout << st1.top() << " ";
		st1.pop();
	}
	cout << endl;

	st::stack<int, std::list<int>> st2;
	st2.push(1);
	st2.push(2);
	st2.push(3);
	st2.push(4);

	while (!st2.empty())
	{
		cout << st2.top() << " ";
		st2.pop();
	}
	cout << endl;
}

void test_queue()
{
	//que::queue<int, vector<int>> q;
	que::queue<int> q1;
	q1.push(1);
	q1.push(2);
	q1.push(3);
	q1.push(4);

	while (!q1.empty())
	{
		cout << q1.front() << " ";
		q1.pop();
	}
	cout << endl;

	que::queue<int, list<int>> q2;
	q2.push(1);
	q2.push(2);
	q2.push(3);
	q2.push(4);

	while (!q2.empty())
	{
		cout << q2.front() << " ";
		q2.pop();
	}
	cout << endl;
}

int main()
{
	test_stack();
	test_queue();
	return 0;
}

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

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

相关文章

实现多线程的三种方式

1. 继承Thread 类实现多线程 想要实现多线程&#xff0c;第一种方法就是通过继承Thread类实现多线程&#xff0c;有以下几步 &#xff08;1&#xff09;我们要先自定义一个类然后继承Thread类&#xff1b; &#xff08;2&#xff09;在继承Trread的类中重写 run 方法&#x…

成功了!|| Poetry安装pytorch || 整理自github项目Poetry下的issue

在使用Poetry安装pytorch的时候&#xff0c;常常会遇到各种问题&#xff1a;首先是使用add添加时&#xff0c;会说只有torch没有什么pytorch&#xff0c;很显然&#xff0c;它是直接针对包的&#xff0c;第二点是&#xff0c;如果是一台没有nvidia显卡的机器&#xff0c;由于po…

CISA《网络安全事件和漏洞响应手册》提到的SSVC是什么?

2021年11月16日&#xff0c;美国网络安全和基础设施安全局(CISA)根据行政命令EO 14028的要求发布了《网络安全事件和漏洞响应手册》。手册规定的漏洞响应过程包括识别、评估、修复、报告通知4个步骤&#xff0c;其中评估部分的第一句话提到“使用特定相关者漏洞分类法(Stakehol…

C++ 动态内存分配

在C中动态内存的分配技术可以保证程序在允许过程中按照实际需要申请适量的内存&#xff0c;使用结束后还可以释放&#xff0c;这种在程序运行过程中申请和释放的存储单元也称为堆。 申请和释放过程一般称为建立和删除。 在C程序中&#xff0c;建立和删除堆对象使用两个运算符&…

html页面input设置日期和时分秒组件方法

html <input class"form-control" type"datetime-local" step"01">效果图

Java根据坐标经纬度计算两点距离(5种方法)、校验经纬度是否在圆/多边形区域内的算法推荐

目录 前言 一、根据坐标经纬度计算两点距离&#xff08;5种方法&#xff09; 1.方法一 2.方法二 3.方法三 4.方法四 5.方法五 5.1 POM引入第三方依赖 5.2 代码 6.测试结果对比 二、校验经纬度是否在制定区域内 1.判断一个坐标是否在圆形区域内 2.判断一个坐标是否…

安防监控国标GB28181平台EasyGBS视频快照无法显示是什么原因?如何解决?

安防视频监控国标视频云服务EasyGBS支持设备/平台通过国标GB28181协议注册接入&#xff0c;并能实现视频的实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。平台部署简单、可拓展性强&#xff0c;支持将接入的视频流进行全终端、全平台分发&#xff…

【Leetcode刷题】模拟

本篇文章为 LeetCode 模拟模块的刷题笔记&#xff0c;仅供参考。 目录 一. 字符串Leetcode43.字符串相乘Leetcode592.分数加减运算Leetcode68.文本左右对齐 二. 矩阵Leetcode54.螺旋矩阵Leetcode885.螺旋矩阵 IIILeetcode498.对角线遍历Leetcode874.模拟行走机器人 三. 数组Lee…

Aligning Large Language Models with Human: A Survey

本文也是LLM相关的综述文章&#xff0c;针对《Aligning Large Language Models with Human: A Survey》的翻译。 对齐人类与大语言模型&#xff1a;综述 摘要1 引言2 对齐数据收集2.1 来自人类的指令2.1.1 NLP基准2.1.2 人工构造指令 2.2 来自强大LLM的指令2.2.1 自指令2.2.2 …

JavaSE【抽象类和接口】(抽象类、接口、实现多个接口、接口的继承)

一、抽象类 在 Java 中&#xff0c;一个类如果被 abstract 修饰称为抽象类&#xff0c;抽象类中被 abstract 修饰的方法称为抽象方法&#xff0c;抽象方法不用 给出具体的实现体。 1.语法 // 抽象类&#xff1a;被 abstract 修饰的类 public abstract class Shape { …

AI.com的命运之战:马斯克如何从OpenAI手中夺走这个价值千万的域名

一、AI.COM AI.com是一个极具价值的域名&#xff0c;它于1993年5月注册&#xff0c;距今已有近30年的历史。2021年2月&#xff0c;人工智能研究机构OpenAI以至少1100万美元&#xff08;约合人民币7535万元&#xff09;的高价&#xff0c;拿下了这个域名。OpenAI是马斯克在2015…

微信小程序中的分包使用介绍

一、分包的好处 可以优化小程序首次启动的下载时间 在多团队共同开发时可以更好的解耦协作 主包&#xff1a;放置默认启动页面/TabBar 页面&#xff0c;公共资源/JS 脚本 分包&#xff1a;根据开发者的配置进行划分 限制&#xff1a;所有分包大小不超过 20M&#xff0c;单…

私有化部署企业IM即时通讯:提升效率、防止泄密、高效协同办公

随着科技的飞速发展和智能手机的普及&#xff0c;即时通讯&#xff08;IM&#xff09;应用在我们的生活和工作中变得越来越重要。在企业中&#xff0c;IM已成为员工之间交流沟通的主要方式之一。然而&#xff0c;对于大多数企业来说&#xff0c;选择私有化部署企业IM即时通讯软…

Pytorch Tutorial【Chapter 2. Autograd】

Pytorch Tutorial 文章目录 Pytorch TutorialChapter 2. Autograd1. Review Matrix Calculus1.1 Definition向量对向量求导1.2 Definition标量对向量求导1.3 Definition标量对矩阵求导 2.关于autograd的说明3. grad的计算3.1 Manual手动计算3.2 backward()自动计算 Reference C…

解决在mybatis中使用class属性绑定映射文件出现的异常问题~

如下所示&#xff0c;当我在XML文件中通过class属性配置其mapper文件时&#xff0c;出现下述错误 <mappers><mapper class"mappers.userMapper"/> </mappers>错误描述&#xff1a; 解决方法如下所示&#xff1a;在pom.xml文件中添加下述代码 <…

【腾讯云Cloud Studio实战训练营】使用React快速构建点餐H5

文章目录 前言一、Cloud Studio是什么二、Cloud Studio特点三、Cloud Studio使用1.访问官网2.账号注册3.模板选择4.模板初始化5.H5开发安装 antd-mobile安装 Less安装 normalize&#xff1a;上传项目需要的素材&#xff1a;替换App.js主文件&#xff1a;项目启动、展示 6.发布仓…

zookeeper安装教程及其基本使用

目录 zookeeper下载&#xff1a; zookeeper下载官网&#xff1a; 本地安装配置&#xff1a; 启动zookeeper&#xff1a; 开启服务端&#xff1a; 启动客户端&#xff1a; 查看zookeeper的状态&#xff1a; zoo.cfg文件解读&#xff1a; zookeeper的集群安装&#xff1a…

Go调试神器pprof使用教程【实战分享】

Go调试神器pprof使用教程 go的GC会自动管理内存&#xff0c;但是这不代表go程序就不会内存泄露了。 go常见产生内存泄露的原因就是goroutine没有结束&#xff0c;简单说就是goroutine 被阻塞了&#xff0c;这样就会导致goroutine引用的内存不被GC回收。 1 概念 在Go中&#xf…

二叉树的性质、前中后序遍历【详细】

1. 树概念2.二叉树的概念1.2二叉树的性质 3.二叉树遍历3.2前序遍历3.2 中序遍历3.3 后序遍历 1. 树概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合&#xff0c;有二叉树&#xff0c;N叉树等等。 子树…