STL模拟实现——stack、queue和priority_queue(适配器、仿函数、反向迭代器)

news2024/11/19 15:34:18

适配器

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结),该种模式是将一个类的接口转换成客户希望的另外一个接口。下列的这些stack、queue和priority_queue以及反向迭代器都是适配器。

stack介绍

1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行 元素的插入与提取操作。

2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定 的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下 操作:

empty:判空操作

back:获取尾部元素操作

push_back:尾部插入元素操作

pop_back:尾部删除元素操作

4. 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器, 默认情况下使用deque。

queue介绍

1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端 提取元素。

2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的 成员函数来访问其元素。元素从队尾入队列,从队头出队列。

3. 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操 作:

empty:检测队列是否为空

size:返回队列中有效元素的个数

front:返回队头元素的引用

back:返回队尾元素的引用

push_back:在队列尾部入队列

pop_front:在队列头部出队列

4. 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标 准容器deque。

priority_queue的介绍

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。

2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元 素)。

3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特 定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。

4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭 代器访问,并支持以下操作:

empty():检测容器是否为空

size():返回容器中有效元素个数

front():返回容器中第一个元素的引用

push_back():在容器尾部插入元素

pop_back():删除容器尾部元素

5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指 定容器类,则使用vector。

6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数 make_heap、push_heap和pop_heap来自动完成此操作。

模拟实现

#pragma once
#include<iostream>
#include<vector>
#include<list>
#include<deque>
using namespace std;
namespace szg
{
	template<class T, class container = deque<T>>
	class stack
	{
	public:
		void push(const T& val)
		{
			_con.push_back(val);
		}

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

		const T& top()
		{
			return _con.back();
		}
		bool empty()
		{
			return _con.empty();
		}

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

		container _con;
	};

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

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

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

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

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

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


	//仿函数
	template<class T>
	class less
	{
	public:
		bool operator()(const T& x, const T& y) const
		{
			return x < y;
		}
	};

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


	template<class T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue()
		{}

		//向上调整
		void adjust_up(size_t child)
		{
			size_t parent = (child - 1) / 2;
			Compare com;
			while (child > 0)
			{
				if (com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
				}
				else
				{
					break;
				}
				child = parent;
				parent = (child - 1) / 2;
			}
		}

		//向下调整
		void adjust_down(size_t parent)
		{
			size_t child = 2 * parent + 1;
			Compare com;
			while (child + 1 < _con.size())
			{
				if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
				{
					++child;
				}
				if (com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
				}
				else
				{
					break;
				}
				parent = child;
				child = 2 * parent + 1;
			}
		}

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

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjust_down(0);
		}

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

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

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

	private:
		Container _con;
	};


}

仿函数

仿函数是一个类,类中对圆括号进行了运算符重载,使用起来像是个函数,为了通过传递不同的模板参数改变类内部实现的逻辑。

//仿函数
	template<class T>
	class less
	{
	public:
		bool operator()(const T& x, const T& y) const
		{
			return x < y;
		}
	};

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

反向迭代器

反向迭代器也是一种适配器。

// 给我不同容器的正向迭代器,适配出对应的这个容器需要的反向迭代器
template<class Iterator, class Ref, class Ptr>
class ReverseIterator
{
	typedef ReverseIterator<Iterator, Ref, Ptr> Self;

public:
	ReverseIterator(Iterator it)
		:_it(it)
	{}

	Ref operator*()
	{
		Iterator tmp = _it;
		return *(--tmp);
	}

	Ptr operator->()
	{
		return &(operator*());
	}

	Self& operator++()
	{
		--_it;
		return *this;
	}

	Self& operator--()
	{
		++_it;
		return *this;
	}

	bool operator!= (const Self& s) const
	{
		return _it != s._it;
	}

private:
	Iterator _it;
};

要注意的一点是:反向迭代器读写数据是读写当前迭代器的前一个。 

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

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

相关文章

数据结构-第八期——树状数组-原理区间和

目录 1、树状数组 2、基本应用 2.1、前缀和&#xff1a;不修改&#xff0c;只查询 2.2、树状数组&#xff1a;动态修改&#xff0c;求区间和 3、实现数组树状 3.1、神奇的lowbit (x)操作 3.2、tree[ ]数组 3.3、基于tree[ ]的计算 3.4 sum[]的计算 3.5、tree[]的更新…

CD3药物研发进展-销售数据-上市药品前景分析

CD3作为近几年的双抗热门靶点之一&#xff0c;目前在全球登记的CD3相关药物就有470个&#xff0c;上市的CD3药物有8款&#xff0c;Ⅰ期临床到Ⅲ期临床有116种&#xff0c;临床前及药物发现达200多种&#xff0c;其火热程度可想而知&#xff0c;笔者为方便大家更加清晰了解CD3在…

ESP-IDF:冒泡排序和选择排序测试代码

ESP-IDF:冒泡排序和选择排序测试代码 /冒泡排序/ void printarry16 (int arr[],int length) { for(int i0;i<length;i) { cout<<arr[i]<<" “; } cout<<endl; } void test16() { int arr[] {9, 8, 7, 6, 5, 4, 3, 2, 1, 0,9, 8, 7, 6, 5, 4, 3, 2…

【笔记】容器基础-容器与虚拟机

杂记&#xff1a; 容器技术的兴起源于 PaaS 技术的普及Docker 公司发布的 Docker 项目具有里程碑式的意义Docker 项目通过“容器镜像”&#xff0c;解决了应用打包这个根本性难题容器本身没有价值&#xff0c;有价值的是“容器编排”进程&#xff1a; 静态表现&#xff1a;程序…

Java NIO同步非阻塞编程原理解析及案例

Java NIO同步非阻塞编程原理解析及案例 文章目录Java NIO同步非阻塞编程原理解析及案例NIO介绍NIO和 BIO的比较NIO 三大核心原理示意图缓冲区(Buffer)基本介绍Buffer常用API介绍Buffer 类及其子类缓冲区对象创建缓冲区对象添加数据缓冲区对象读取数据通道(Channel)基本介绍Chan…

生物医药校招这么难,怎么锁定高端人才?

“每年招聘压力大&#xff0c;进校太难。”“各个事业部人才选用要求高&#xff0c;很难达到要求。”“企业、事业单位、高校三方‘围剿’&#xff0c;人才竞争实在太大&#xff01;”……人才招聘内卷&#xff0c;在生物医药行业可以说是体现得淋漓尽致。生物医药岗位及学历要…

【小白课程】以openKylin看图软件为例,浅谈图片编解码库—FreeImage

看图软件是openKylin操作系统上一款开源的图像查看软件&#xff0c;支持对图片进行基本操作,如&#xff1a;缩放、翻转、详情查看、复制、打印、重命名等&#xff0c;同时还可以对图片进行裁剪、存储、标注和ocr&#xff08;文字识别&#xff09;。 图1 看图软件界面 作为图像…

信通院联合偶数科技等企业发布《云原生湖仓一体白皮书》

2023年1月9日&#xff0c;云原生产业联盟在今年年会上重磅发布了《云原生湖仓一体白皮书》。该白皮书由中国信通院牵头&#xff0c;偶数科技、中国人寿、中信建投、中国联通等单位共同编写。 本次白皮书从云原生湖仓的发展历程、技术方案、生态现状、实践案例等方面进行了全面深…

Linux C 捕捉 Ctrl+C 的SIGINT信号

kill -l可以看每个数字对应的信号信号值9和15的区别&#xff1a;kill命令默认是-15&#xff0c;代表的信号为SIGTERM&#xff0c;在结束此进程之前&#xff0c;允许此进程做一些清理工作kill -9会直接杀死目标进程&#xff0c;不给其机会做清理工作按键盘的 CtrlC时&#xff0c…

测试高薪必备

测试人员由于工作原因要经常检查数据库的数据是否正确&#xff0c;这个时候就需要频繁使用多表查询。 在多表查询中&#xff0c;应用最多的就是内连接&#xff0c;其次就是子查询。 为什么子查询是在工作中应用也有这么广泛的应用呢&#xff1f;原因在于子查询非常方便…

macOS下使用vscode+xdebug调试php

手动安装xdebug1、浏览器访问https://xdebug.org/wizard2、在本地终端输入php -i 命令&#xff0c;将输出的内容复制到指南中的输入框中并提交分析3、分析完后会给出分析概览&#xff0c;然后根据下面提示步骤进行手动安装即可第5步中的phpize 命令位置:/usr/local/Cellar/php7…

神经网络基础与原理

7.1 神经网络基础与原理 学习目标 目标 了解感知机结构、作用以及优缺点了解tensorflow playground的使用说明感知机与神经网络的联系说明神经网络的组成说明神经网络的分类原理说明softmax回归说明交叉熵损失应用 无 7.1.1 神经网络 人工神经网络&#xff08; Artificial N…

Oracle数据库卸载安装

卸载oracle步骤&#xff1a;1.首先关掉所有oracle的相关服务&#xff0c;然后找到oracle的卸载程序Universal Installer&#xff1a;2.卸载&#xff0c;删除所有应用然后继续点击卸载产品&#xff0c;然后点击展开全部&#xff0c;将主目录以外的所有应用全部卸载掉&#xff0c…

【C语言】C语言中a<b<c与a<bb<c的区别你注意到了嘛?

问题导入   今天碰到了一个if(a<b<c)逻辑一直成立&#xff0c;无论a,b,c三者的值如何&#xff0c;输出结果一直一样。&#x1f605;&#x1f605;&#x1f605;大家可以看看下图&#xff1a; 逻辑运算测试1 不过讲实话&#xff0c;在实际写代码过成中&#xff0c;小编一…

【数据结构基础】树 - 哈夫曼树(Huffman Tree)

哈夫曼又称最优二叉树, 是一种带权路径长度最短的二叉树。(注意带权路径WPL是指叶子节点&#xff0c;很多网上的文章有误导) 哈夫曼树相关名词先看一棵哈夫曼树: (哈夫曼树推理是通过叶子节点&#xff0c;所以理解的时候需要忽略非叶子节点&#xff0c;很多文章在这点上有误导)…

CHAPTER 14 Swarm

Swarm14.1 Swarm简介14.2 Swarm vs K8s14.3 基本概念1. Swarm集群2.节点3.服务4.任务5.服务的外部访问14.4 使用Swarm1.创建集群(init)2.查看集群信息(info)3.加入集群(join)4.使用集群服务(service)1. 创建服务(service create)2. 查看服务(service ls)3. 扩缩服务(service sc…

力扣:至少是其他数字两倍的最大数(详解)

前言&#xff1a;本期是关于至少是其他数字两倍的最大数的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读&#xff0c;今天你c了吗&#xff1f; 题目&#xff1a; 给你一个整数数组 nums &#xff0c;其中总…

如何对企业网站进行优化?(网站怎样优化seo)

探析企业网站优化怎么做才有效果&#xff1f; 在互联网营销时代&#xff0c;搜索引擎一直是推广流量的重要途径&#xff0c;越来越多的企业已经涉足搜索引擎优化行业&#xff0c;众多企业做网站优化是为了网站提升企业知名度和流量&#xff0c;争取以更低成本做更高转化、更快…

公务机包机|公务飞行包机攻略解答

公务机是一种在行政事务和商业活动中用作交通工具的飞行&#xff0c;也被称为行政机或商用飞机。公务机包机程序简单&#xff0c;不仅可以享受不一致的尊崇服务&#xff0c;而且可以避免巨额投资和日常管理的繁琐事务。    公务机是指在行政事务和商业活动中用作交通工具的飞…

最重要的定理:隐函数定理

多元函数变限积分求导问题