【C++】stack | queue | priority_queue的模拟实现

stack&queue的模拟实现

stack 与 queue 作为容器适配器,都默认选择了 deque 作为其底层容器。

#pragma once
#include <deque>
using namespace std;

namespace zs
{
	template<class T, class Container = deque<T>>
	class stack
	{
	public:
		void push(const T& val)
		{
			_cont.push_back(val);
		}

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

		T& top()
		{
			return _cont.back();
		}

		const T& top() const
		{
			return _cont.back();
		}

		bool empty() const 
		{
			return _cont.empty();
		}

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

	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		void push(const T& val)
		{
			_cont.push_back(val);
		}

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

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

		const T& front() const
		{
			return _cont.front();
		}

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

		const T& back() const
		{
			return _cont.back();
		}

		bool empty() const
		{
			return _cont.empty();
		}

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

deque 的介绍

deque(双端队列) 是一种双开口的“连续”空间的数据结构。
双开口是指,可以在头尾两端进行插入删除,且时间复杂度都是O(1)。
但deque并不是真的连续的物理空间,而是由一段又一段连续的小空间拼接而成的。
在这里插入图片描述
为什么会选择 deque 作为 stack 和 queue 的默认底层容器呢?
与 vector 相比,deque 头部插入删除效率高,扩容也不需要搬移大量的元素。
与 list 相比,空间利用率更高,不需要存储额外字段。
deque 也有很多缺陷:
deque 的底层结构决定了它的迭代器设计会很复杂。
遍历以及对数据的随机访问效率会比较低。
完成对中间数据的插入删除操作也会更复杂。
stack 和 queue 的特点能够很好地规避 dqeue 的缺陷,而充分利用到了 deque 的优点,而且这也是 deque 为数不多的应用中的一个。

priority_queue的模拟实现

priority_queue(优先级队列)其实就是一个堆结构,默认使用 vector 作为其底层容器。

#pragma once
#include <vector>
using namespace std;

namespace zs
{
	// Compare 进行比较的仿函数 默认less->大堆 greater->小堆
	template<class T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue()
		{}

		template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_cont.push_back(*first);
				++first;
			}

			// 向下建堆
			for (int i = (_cont.size() - 1 - 1) / 2; i >= 0 ; --i)
			{
				adjust_down(i);
			}
		}

		void adjust_up(size_t child)
		{
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_cont[child] > _cont[parent])
				//if (_cont[parent] < _cont[child])
				if (Compare()(_cont[parent], _cont[child]))
				{
					::swap(_cont[parent], _cont[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

		void push(const T& val)
		{
			_cont.push_back(val);
			adjust_up(_cont.size() - 1);
		}

		void adjust_down(size_t parent)
		{
			size_t child = parent * 2 + 1;

			while (child < _cont.size())
			{
				//if (child + 1 < _cont.size() && _cont[child + 1] > _cont[child])
				//if (child + 1 < _cont.size() && _cont[child] < _cont[child + 1])
				if (child + 1 < _cont.size() && Compare()(_cont[child], _cont[child + 1]))
				{
					++child;
				}
				//if (_cont[child] > _cont[parent])
				//if (_cont[parent] < _cont[child])
				if (Compare()(_cont[parent], _cont[child]))
				{
					::swap(_cont[parent], _cont[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			::swap(_cont.front(), _cont.back());
			_cont.pop_back();

			adjust_down(0);
		}

		const T& top() const
		{
			return _cont.front();
		}

		bool empty() const
		{
			return _cont.empty();
		}

		size_t size() const
		{
			return _cont.size();
		}

	private:
		Container _cont;
	};

	/*
	*  仿函数,也叫函数对象,主要还是一个类
	*  因为重载了operator(), 可以像函数一样使用
	*/
	template<class T>
	class less
	{
	public:
		bool operator()(const T& val1, const T& val2) const
		{
			return val1 < val2;
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& val1, const T& val2) const
		{
			return val1 > val2;
		}
	};
}

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

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

相关文章

C#之泛型

目录 一、概述 二、C#中的泛型 继续栈的示例 三、泛型类 &#xff08;一&#xff09;声明泛型类 &#xff08;二&#xff09;创建构造类型 &#xff08;三&#xff09;创建变量和实例 &#xff08;四&#xff09;比较泛型和非泛型栈 四、类型参数的约束 &#xff08;一…

iOS--runtime

什么是Runtime runtime是由C和C、汇编实现的一套API&#xff0c;为OC语言加入了面向对象、运行时的功能运行时&#xff08;runtime&#xff09;将数据类型的确定由编译时推迟到了运行时平时编写的OC代码&#xff0c;在程序运行过程中&#xff0c;最终会转换成runtime的C语言代…

“华为杯”研究生数学建模竞赛2019年-【华为杯】D题:汽车行驶工况构建

目录 摘 要&#xff1a; 1.问题背景与问题重述 1.1 问题背景 1.2 问题重述 2.模型假设 3.符号说明 4.问题一的求解 4.1 问题分析 4.2 异常数据的处理 4.2.1 明显错误数据的处理 4.2.2 加减速异常数据的处理 4.3 缺失数据的处理 4.3.1 数据插补处理 4.3.2 视为长期停车处理 4.3.…

64核RISC-V服务器能打了吗?

作者&#xff1a;西风烈 最近看到“澎峰科技”的微信公众号&#xff0c;看到他们发布了第一款RISC-V服务器&#xff0c;芯片是算能的SG2042&#xff0c;带64个RISC-V核心&#xff08;阿里平头哥的C910v核&#xff09;&#xff0c;2.0GHz主频&#xff0c;最大支持128GB内存。这…

用CSS和HTML写一个水果库存静态页面

HTML代码&#xff1a; <!DOCTYPE html> <html> <head><link rel"stylesheet" type"text/css" href"styles.css"> </head> <body><header><h1>水果库存</h1></header><table>…

问道管理:股利支付率和股利发放率一样吗?

股利是指公司在股票发行后向股东分配的收益。股利付出率和股利发放率是两个在股利分配方面非常重要的概念。很多人会以为这两个概念是相同的&#xff0c;但实践上它们是有差异的。在本文中&#xff0c;咱们将从不同的角度来分析这两个概念的差异和联络。 一、股利付出率和股利发…

计算机毕设 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

文章目录 0 前言1.前言2.实现效果3.相关技术原理3.1卷积神经网络3.1YOLOV5简介3.2 YOLOv5s 模型算法流程和原理4.数据集处理3.1 数据标注简介3.2 数据保存 5.模型训练 6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题…

容灾独家技术揭秘:HyperBDR无主机数据同步技术

01、一对一单机热备-传统灾备方式 单机热备是一种备份解决方案&#xff0c;它使用两台服务器来确保高可用性&#xff0c;是市场上最为常见的灾备模式。 在单机热备中&#xff0c;一台主服务器和一台备用服务器保持同步&#xff0c;以确保在主服务器出现故障或宕机时可以立即切换…

【数据分析专栏之Python篇】四、pandas介绍

前言 在上一篇中我们安装和使用了Numpy。本期我们来学习使用 核心数据分析支持库 Pandas。 一、pandas概述 1.1 pandas 简介 Pandas 是 Python 的 核心数据分析支持库&#xff0c;提供了快速、灵活、明确的数据结构&#xff0c;旨在简单、直观地处理关系型、标记型数据。 …

微服务体系<2> ribbon

1. 什么是负载均衡 比如说像这样 一个请求打在了nginx上 基于nginx进行负载分流 这就是负载均衡但是负载均衡分 服务端负载均衡和客户端负载均衡 客户端负载均衡 我user 从注册中心拉取服务 拉取order列表&#xff0c;然后发起getOne()调用 这就是客户端负载均衡 特点就是我…

Servlet详解

1、Servlet 1、Java支持动态网页的技术&#xff1a;直接编写Java&#xff0c;利用CGI的方式与WebServer沟通 2、servlet在MVC中相当于控制层的作用。 Servlet的作用&#xff1a; CGI&#xff1a;通用网关接口&#xff1a;是从WEB容器中取得数据&#xff08;内置对象&#x…

基于 ThinkPHP 5.1(稳定版本) 开发wms 进销存系统源码

基于ThinkPHP 5.1&#xff08;LTS版本&#xff09;开发的WMS进销存系统源码 管理员账号密码&#xff1a;admin 一、项目简介 这个系统是一个基于ThinkPHP框架的WMS进销存系统。 二、实现功能 控制台 – 权限管理&#xff08;用户管理、角色管理、节点管理&#xff09; – 订…

Java课题笔记~Maven基础知识

一、什么是Maven&#xff1f; Maven是专门用于管理和构建Java项目的工具。 它的主要功能有&#xff1a; 提供了一套标准化的项目结构提供了一套标准化的构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布……&#xff09;提供了一套依赖管理机制 …

认识 springboot 之 它的配置文件 -2

前言 本篇了解springboot中配置的作用&#xff0c;介绍配置文件的种类&#xff0c;介绍简单使用配置文件&#xff0c;简单的小技巧如何设置注释&#xff0c;开启热部署等等&#xff0c;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&…

查找-多路查找详解篇

多路查找树 多路查找树&#xff08;Multway Search Tree&#xff09;是一种高级的树形数据结构&#xff0c;它 允许每个节点有多个子节点&#xff08;通常大于等于2&#xff09;。多路查找树的每个节点 可以存储多个关键字和对应的值。分类 2-3树&#xff08;2-3 Tree&#x…

Vite+Vue3 开发UI组件库并发布到npm

一直对开源UI组件库比较感兴趣&#xff0c;摸索着开发了一套&#xff0c;虽然还只是开始&#xff0c;但是从搭建到发布这套流程基本弄明白了&#xff0c;现在分享给大家&#xff0c;希望对同样感兴趣的同学有所帮助。 目前我的这套名为hasaki-ui的组件库仅有两个组件&#xff0…

FitBot-一款先进的以健康为中心的聊天机器人

在健康意识高涨&#xff0c;追求均衡生活方式成为普遍追求的时代&#xff0c;营养问题无疑是核心支柱。然而&#xff0c;饮食计划的复杂性和大量的营养数据往往成为我们实现这种平衡的障碍。例如糖尿病患者&#xff0c;他们需要持续和准确的营养指导来有效管理血糖水平。如果能…

框架的知识点整理

目录 1、什么是Spring框架&#xff1f;Spring框架有哪些主要模块&#xff1f; 2 、 使用Spring框架有什么好处&#xff1f; 3、Spring MVC 工作原理 1、什么是Spring框架&#xff1f;Spring框架有哪些主要模块&#xff1f; Spring框架是一个开源的轻量级的Java应用程序开…

Spring事务创建与使用

目录 前言Spring中事务的实现声明式事务Transactional 作⽤范围Transactional 参数说明对于事务不回滚的解决方案 前言 在数据库中我们提到了 事务, 事务的定义为, 将一系列操作封装成一个整体去调用 , 要么一起成功, 要么一起失败 Spring中事务的实现 在Spring中事务的操作…

电动汽车市场的减速,正在让小鹏汽车付出代价

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;由于价格压力上升、竞争加剧和需求减弱&#xff0c;小鹏汽车的交付量出现了明显下滑&#xff0c;6月份的交付量已经同比下降了43%。 &#xff08;2&#xff09;小鹏汽车对2023年…
最新文章