【C++】STL中的容器适配器 stack queue 和 priority_queue 的模拟实现

news2025/3/11 1:13:29

STL中的容器适配器

  • 一、容器适配器
    • 1、什么是容器适配器
    • 2、STL标准库中的容器适配器
  • 二、stack的模拟实现
    • 1、stack的简单介绍
    • 2、栈的模拟实现
  • 三、queue的模拟实现
    • 1、queue的简单介绍
    • 2、queue的模拟实现
  • 四、priority_queue的模拟实现
    • 1、priority_queue的简单介绍
    • 2、priority_queue的模拟实现

一、容器适配器

1、什么是容器适配器

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

例如我们常见的充电器就是一种适配器,它将我们常用的220V交流电压转化为4,5V (或者其他更高的电压) 的直流电压来给我们的电子设备进行充电。

2、STL标准库中的容器适配器

虽然stackqueue priority_queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配

器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stackqueue默认使用dequepriority_queue默认使用了vector

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、stack的模拟实现

1、stack的简单介绍

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

  • empty:判空操作
  • back:获取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部删除元素操作

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

2、栈的模拟实现

为了栈的通用性,这里我们使用模板来进行模拟栈,关于栈的底层容器这里我们选择vector来进行模拟实现。

template<class T, class Container = vector<T>>
class stack
{
public:
	//栈的插入
	void push(const T& val)
	{
		//使用底层容器中尾插函数进行插入,栈只能进行栈顶插入和删除
		_con.push_back(val);
	}
	//栈的删除
	void pop()
	{
		//使用底层容器中尾删函数进行插入,栈只能进行栈顶插入和删除
		_con.pop_back();
	}
	//获取栈顶元素
	T& top()
	{
		//返回底层容器中最后一个数据
		return _con.back();
	}
	//const 版本
	const T& top() const
	{
		return _con.back();
	}
	//获取数据个数
	size_t size() const
	{
		//返回底层容器中数据的个数
		return _con.size();
	}
	//判空函数
	bool empty() const
	{
		//对底层容器进行判空
		return _con.empty();
	}
private:
	//成员变量是一个容器创建的对象
	Container _con;
};

三、queue的模拟实现

1、queue的简单介绍

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

  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列

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

2、queue的模拟实现

为了queue的通用性,这里我们使用模板来进行模拟queue,关于queue的底层容器这里我们选择list来进行模拟实现。

template<class T, class Container = list<T>>
class queue
{
public:
	//队列的插入
	void push(const T& val)
	{
		//使用底层容器中尾插函数进行插入,队列只能进行队尾插入
		_com.push_back(val);
	}
	//队列的删除
	void pop()
	{
		//使用底层容器中头删函数进行删除,队列只能进行队头删除
		_com.pop_front();
	}
	//获取队头数据
	T& front()
	{
		//返回底层容器中第一个数据
		return _com.front();
	}
	//const版本
	const T& front() const
	{
		return _com.front();
	}
	//获取队尾数据
	T& back()
	{
		//返回底层容器中最后一个数据
		return _com.back();
	}
	//const版本
	const T& back() const
	{
		return _com.back();
	}
	//获取数据个数
	size_t size() const
	{
		//返回底层容器中数据的个数
		return _com.size();
	}
	//判空函数
	bool empty() const
	{
		//对底层容器进行判空
		return _com.empty();
	}
private:
	//成员变量是一个容器创建的对象
	Container _com;
};

四、priority_queue的模拟实现

1、priority_queue的简单介绍

相关文档
优先队列是一种容器适配器,它其实就是我们数据结构中的,默认情况下priority_queue是大堆。

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

  • empty:检测容器是否为空
  • size:返回容器中有效元素个数
  • front:返回容器中第一个元素的引用
  • push_back:在容器尾部插入元素
  • pop_back:删除容器尾部元素

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

2、priority_queue的模拟实现

与前面的栈与队列一样priority_queue前两个模板参数都类似,但是priority_queue要有第三个模板参数,这个参数表示按照什么方式进行比较,即建立大堆还是小堆。

//第三个参数是比较方式,需要传递一个仿函数来确定比较方式,默认传递的是less<T>,表示建大堆
template<class T, class Container = vector<T>, class Comper = less<T>>
class priority_queue
{
public:
	//获取堆顶数据
	const T& top() const
	{
		//返回底层容器的第一个数据
		return _con.front();
	}
	//获取数据个数
	size_t size() const
	{
		//返回底层容器的数据个数
		return _con.size();
	}
	//判空函数
	bool empty() const
	{
		//判断底层容器是否为空
		return _con.empty();
	}
	//堆的插入
	void push(const T& val)
	{
		//从尾部插入
		_con.push_back(val);
		int child = _con.size() - 1;
		//向上调整重新建堆
		AdjustUp(child);
	}
	//堆的删除
	void pop()
	{
		//检查堆是否为空
		assert(!_con.empty());
		//交换堆顶与最后一个数据
		swap(_con.front(), _con.back());
		//删除最后一个数据
		_con.pop_back();
		//从堆顶进行向下调整,重新建堆
		AdjustDown(0);
	}
	
private:
	//向上调整算法
	void AdjustUp(int child)
	{
		Comper com;
		int parent = (child - 1) / 2;
		while (child > 0)
		{
			//这里使用了仿函数来判断建立什么堆
			//比较的位置(_con[parent], _con[child])是不能换的!!!
			if (com(_con[parent], _con[child]))
			{
				swap(_con[parent], _con[child]);
				child = parent;
				parent = (child - 1) / 2;
			}
			else
			{
				break;
			}
		}
	}
	//向下调整算法
	void AdjustDown(int parent)
	{
		Comper com;
		//默认左孩子更符合建堆的要求
		int child = parent *2 + 1;
		while (child < _con.size())
		{
			if (child + 1 < _con.size() && Comper()(_con[child], _con[child + 1]))
			{
				++child;
			}

			if (com(_con[parent], _con[child]))
			{
				swap(_con[parent], _con[child]);
				parent = child;
				child = parent * 2 + 1;
			}
			else
			{
				break;
			}
		}
	}
	//成员变量是一个容器创建的对象
	Container _con;
};

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

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

相关文章

家用洗地机哪款好用?好用的洗地机分享

要说现在家居清洁用什么单品更省心&#xff0c;洗地机必须要算一项。虽然这在国际上也不是什么新鲜的概念了&#xff0c;但是在国内兴起也只是这几年的事&#xff0c;关于家用洗地机什么牌子最好之类的问题也是很多人都比较关心的问题。我个人也是不喜欢做家务的&#xff0c;家…

Anaconda及其他说明及安装

来自神秘人的投稿&#xff01; 以下内容来源于官方视频说明&#xff1a;Anaconda Distribution versus Miniconda和其他整理与添加。 一、基础信息了解 1. 什么是Anaconda Anaconda Distribution&#xff1a;形象的比喻——一台笔记本电脑&#xff0c;一切都组装好了&#x…

利用用户生成内容来促进您的 WooCommerce 商店的销售

用户生成内容 (UGC) 是由对品牌或其产品和服务进行评论或评论的消费者创建的内容。它可以包括评论、照片、博客文章、推文或任何类型的社交媒体内容。 UGC 可以应品牌要求制作&#xff0c;也可以由产品用户独立制作。当用户生成的内容是独立制作的时候——比如一个新布加迪手…

UG NX二次开发(C#)-建模-移除特征参数

文章目录 1、前言2、在UG NX中的操作3、 利用UFun函数实现1、前言 UG NX建模方式是采用特征建模的,创建一个对象都是一个特征,这在历史记录中可以查看特征的建模历史、特征的参数已经特征之间的关联关系。有时为了设计的需要,需要去除特征之间的关联关系,那么就要移除特征…

【硬件外设使用】——ADC

【硬件外设使用】——ADC ADC基本概念ADC使用方法pyb.adcmachine.adc ADC可用的传感器 ADC基本概念 ADC是模拟数字转换器&#xff08;Analog-to-Digital Converter&#xff09;的缩写&#xff0c;它是一种将模拟信号转换成数字信号的电子元件。 ADC广泛用于测量和监测领域&…

sggJava基础第四天

1 分支结构 分支结构 根据条件&#xff0c;选择性地执行某段代码。 有if…else和switch-case两种分支语句。 概述 顺序结构的程序虽然能解决计算、输出等问题 但不能做判断再选择。对于要先做判断再选择的问题就要使用分支结构 if…else形式 单分支结构 代码实现 …

leetcode160. 相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&…

把脉分布式事务的模型、协议和方案

在当前的技术发展阶段&#xff0c;不同的业务场景对一致性、可靠性、易用性、性能等要求不同&#xff0c;应用架构可以根据实际场景的需求&#xff0c;灵活选择合适的分布式事务解决方案。行业中把分布式事务解决方案分为刚性事务方案和柔性事务方案这两大类。 就刚性事务这个…

leetcode328. 奇偶链表

给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个节点的索引被认为是 奇数 &#xff0c; 第二个节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xff0c;偶数组和奇数组内部的相…

CentOS 7安装GitLab、创建用户、创建Repo、拉取推送

效果图 前言 gitlab全球出名&#xff0c;包含免费的社区版CE、收费的企业版EE&#xff0c;在国内安装速度一般&#xff1b; gitlab极狐版是中国特供版&#xff0c;用起来就跟CE一样&#xff0c;推荐国内使用~ 实现步骤 - 安装&配置 先准备好gitlab服务对外的访问地址&am…

技术分享 | MySQL级联复制下进行大表的字段扩容

作者&#xff1a;雷文霆 爱可生华东交付服务部 DBA 成员&#xff0c;主要负责Mysql故障处理及相关技术支持。爱好看书&#xff0c;电影。座右铭&#xff0c;每一个不曾起舞的日子&#xff0c;都是对生命的辜负。 本文来源&#xff1a;原创投稿 *爱可生开源社区出品&#xff0c;…

使用Vite工具构建OpenLayers应用

vite作为最近大火的前端构建工具,吸引了大批开发者和工具框架作者的关注。vite自称为下一代的构建工具,这是要取代webpack的节奏啊。openlayers最新版本的案例代码就使用了vite来构建,因此这一篇文章我们来给大家示范一下如何使用vite来构建一个基于openlayers的应用。 首先…

从「搭子」文化,看融云如何助力垂类社交应用增长

互联网人拜佛 be like &#x1f446;&#xff0c;主打的就是一个垂直和精准。关注【融云全球互联网通信云】了解更多 其实&#xff0c;这也是年轻人的交友现状。最近随着大学生“特种兵式”旅游出圈的“搭子”友情&#xff0c;就是这样。 “搭子”&#xff0c;AKA 垂直细分领…

怎么把图片拼接成长图,3招教你快速处理

怎么把图片拼接成长图的方法&#xff0c;有没有快速便捷可一键操作的呢&#xff1f;当我们把图片拼接成长图有很多优点&#xff0c;比如说我们在图片文件传输的时候就更加快捷方便&#xff0c;还有就是我们在图片展示的时候更加统一。虽然有这么多优点&#xff0c;但是如果我们…

【RobotFramework自动化测试】

robotframework介绍 RF是一个基于Python语言开发的&#xff0c;可扩展的&#xff0c;是以关键字驱动模式的自动化测试框架。RF最新的版本是2019 年7月份发布&#xff0c;7月份之前只支持python2.7&#xff0c;7月之后支持3.X的版本 robotframework的安装 安装python环境&…

【JUC】CAS

【JUC】CAS 文章目录 【JUC】CAS1. 概述2. Unsafe类 1. 概述 在Java并发编程中&#xff0c;CAS是一种非阻塞的算法&#xff0c;即Compare and Swap&#xff08;比较并交换&#xff09;。 CAS通过比较内存中某个位置的值和预期值&#xff0c;如果相同&#xff0c;则将该位置的…

springcloud各个组件搭配使用演示

springcloud各个组件使用demo Eureka服务注册中心 创建三个eureka服务注册中心,分别为: eureka-server1 spring:application:name: eureka-server1 server:port: 8001eureka:client:service-url:defaultZone: http://localhost:8002/eureka/,http://localhost:8003/eureka/…

EtherCAT和Ethernet的不同点有哪些, 通信周期又是什么意思?

小伙伴们&#xff0c;我们又来了。上期大概介绍了EtherCAT的一些特性&#xff0c;本期我们将会更详细的介绍一下EtherCAT的实现方式&#xff0c;通信周期的意义到底是什么、SDO和PDO到底是什么等概念。 首先要声明&#xff0c;尽管本期介绍略微深入&#xff0c;实际上小伙伴使…

超详细!腾讯NLP算法岗面经(已offer)

作者 | ZipZou 整理 | NewBeeNLP 面试锦囊之面经分享系列&#xff0c;持续更新中 可以后台回复"面试"加入交流讨论组噢 分享一篇旧文&#xff0c;希望大家都成功上岸~ 写在前面 首先来段简单的自我介绍&#xff1a;2021届硕士&#xff0c;硕士期间未有实习经历&…

【Micropython】ESP8266通过NTP同步本地RTC时间

【Micropython】ESP8266通过NTP同步本地RTC时间 &#x1f4cc;相关篇《【MicroPython esp8266】固件烧写教程》✨本案例基于Thonny平台开发。✨ &#x1f4cb;实时时钟 (RTC) &#x1f516;RTC属于machine模块中的子类。 datetime([value]): 获取或设置当前时间。如果没有指定…