C++ priority_queue 优先级队列

news2024/12/23 18:27:53

一.什么是priority_queue(优先级队列)

优先级队列是一种容器适配器,数据的存储是采用堆的形式实现的,保证第一个元素是优先级队列的最大值或最小值。(默认建大堆)

默认用vector作为底层数据的存储容器。

二.priority_queue的三个类模板参数

1.class T

T是优先级队列中存储元素的类型

2.class Container = vector<T>

Container是优先队列底层使用的存储结构(默认用vector)

3.class Compare = less<typename Container::value_type>

Compare是定义元素比较的方式。(默认less建大堆)

为什么根据Compare可以对元素进行比较呢?

首先我们要了解什么是仿函数。

仿函数

仿函数实际上是一个类的对象,通过operator() 运算符重载来模拟函数调用的过程。

可以利用模板对不同元素进行比较。

因为要建小堆或者大堆,比较方式会不同。就需要Compare接收不同的类来改变比较方式。

template<class T>
class less
{
public:
	bool operator()(T a, T b)
	{
		return a < b;
	}
};
template<class T>
class greater
{
public:
	bool operator()(T a, T b)
	{
		return a > b;
	}
};
	template<class T, class Container = vector<T>,class Compare=less<T>>
	class PriorityQueue
	{
	public:
		PriorityQueue() = default;//强制生成默认构造
		template <class InputIterator>
		PriorityQueue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				c.push_back(*first);
				first++;
			}
			size_t parent = (c.size() - 1 - 1) / 2;
			while (parent > 0)
			{
				size_t child = parent * 2 + 1;
				if (child + 1 < c.size() && comp(c[child], c[child + 1]))
				{
					child++;
				}
				if (c[parent] < c[child]) swap(c[parent], c[child]);
				parent--;
			}
		}
	private:
		Container c;
		Compare comp;
	};
}

建大堆就传入less类,小堆就传入greater类

自定义类型比较

如果优先级队列中存入的是自定义类型,那应该怎么进行比较呢?
这就需要我们在自定义类型的类中重载大于> 小于< 。这样在less greater类的函数中就可以对><进行重载,实现大小的比较。

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	bool operator<(const Date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}

	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}

	friend ostream& operator<<(ostream& _cout, const Date& d);
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}

但如果我要存入Date对象的地址呢?
less greater类中函数直接比较的就是地址的大小。

那我们可以新建一个类,先对地址解引用,在利用函数重载进行比较。

struct PDateLess
{
	bool operator()(Date* p1, Date* p2)
	{
		return *p1 < *p2;
	}
};
struct PDateGreater
{
	bool operator()(Date* p1, Date* p2)
	{
		return *p1 > *p2;
	}
};
void TestPriorityQueue()
{
	// 大堆,需要用户在自定义类型中提供<的重载
	wws::PriorityQueue<Date*, vector<Date*>, PDateLess> q1;
	q1.push(new Date(2024, 6, 1));
	q1.push(new Date(2024, 6, 2));
	q1.push(new Date(2024, 6, 3));

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

三.priority_queue模拟实现

#pragma once
#include<iostream>
using namespace std;
#include<vector>
namespace wws
{

	template<class T>
	class less
	{
	public:
		bool operator()(T a, T b)
		{
			return a < b;
		}
	};
	template<class T>
	class greater
	{
	public:
		bool operator()(T a, T b)
		{
			return a > b;
		}
	};
	template<class T, class Container = vector<T>,class Compare=less<T>>
	class PriorityQueue
	{
	public:
		PriorityQueue() = default;//强制生成默认构造

		template <class InputIterator>
		PriorityQueue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				c.push_back(*first);
				first++;
			}
			size_t parent = (c.size() - 1 - 1) / 2;
			while (parent > 0)
			{
				size_t child = parent * 2 + 1;
				if (child + 1 < c.size() && comp(c[child], c[child + 1]))
				{
					child++;
				}
				if (c[parent] < c[child]) swap(c[parent], c[child]);
				parent--;
			}
		}
		void push(const T& x)
		{
			c.push_back(x);
			size_t child = c.size() - 1;
			while (child > 0)
			{
				size_t parent = (child - 1) / 2;
				if (comp(c[parent] , c[child]))
				{
					swap(c[parent], c[child]);
					child = parent;
				}
				else break;
			}
		}
		void pop()
 		{
			swap(c[0], c[(c.size() - 1)]);
			c.pop_back();
			size_t parent = 0, child = parent * 2 + 1;
			while (child<c.size())
			{
				if (child + 1 < c.size() && comp(c[child], c[child+1]))
				{
					child++;
				}
				if (comp(c[parent], c[child]))
				{
					swap(c[parent], c[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else break;
			}
		}
		bool empty() const
		{
			return c.empty();
		}

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

		const T& top() const
		{
			return c.front();
		}
	private:
		Container c;
		Compare comp;
	};
}

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

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

相关文章

聚观早报 | 苹果预热WWDC24;怪兽充电第一季度营收

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月5日消息 苹果预热WWDC24 怪兽充电第一季度营收 vivo Watch GT设计细节 长城汽车关闭欧洲总部 小米MIX Flip将…

MongoDB下载安装入门 + SpringBoot简单集成

MongoDB安装入门 SpringBoot简单集成 MongoDB下载安装下载安装连接图形化界面MongoDB Compass Navicat Premium Spring Boot集成API操作添加maven配置数据库连接调用Mongo API MongoDB下载安装 下载安装 MongoDB官网地址&#xff1a;https://www.mongodb.com/ 下载地址&…

AI-WEB-1 vulnhub靶场

AI-WEB-1 端口扫描 仅开放80端口 访问80端口 啥也没有 目录扫描 查看robots.txt 发现两个新目录 Disallow: /m3diNf0/ Disallow: /se3reTdir777/uploads/全都无权限访问 加入路径后再次扫描目录 发现/m3diNf0/目录下存在info.php&#xff0c;/se3reTdir777/目录下存在ind…

HTML动态爱心

写在前面 本文主要是对某音爆火的html爱心代码做简单的解析&#xff0c;需要代码文末自取哦~ HTML入门 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语言&#xff0c;用于创建网页。它由一系列的标签组成&#xff0c;这些标签可以告诉浏览器如何显示网…

先进工艺的DPT技术

“2.5GHz频率 hierarchy DVFS低功耗A72培训” 2.5GHz 12nm 景芯A72 upf DVFS 后端实战训练营&#xff01;随到随学&#xff01; 课程采用hierarchy/partition flow&#xff0c;先完成单核A72实战&#xff0c;然后完成A72 TOP实战&#xff01;训练营简介&#xff1a; Instance&a…

斯坦福抄袭清华、面壁智能大模型,当事人已道歉、删项目

6月4日&#xff0c;两名斯坦福大学生Aksh Garg和Siddharth Sharma&#xff0c;承认抄袭清华和面壁智能联合开发的MiniCPM-Llama3-V2.5&#xff08;以下简称V2.5&#xff09;多模态大模型事件&#xff0c;并在社交平台公开道歉、删掉开源项目。 该抄袭事件也得到了斯坦福大学AI…

【计算机毕业设计】302微信小程序的充电桩管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

「漏洞复现」用友NC pagesServlet SQL注入漏洞(XVE-2024-13067)

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

LangChain Agent 最新教程详解及示例学习

LangChain Agent的终极指南&#xff0c;本教程是您使用 Python 创建第一个agent的重要指南&#xff0c;请立即开始你的 LLM 开发之旅。 一、什么是LangChain Agent&#xff08;代理&#xff09; LangChain中代理背后的想法是利用语言模型以及要执行的一系列操作。代理正在使用…

`THREE.BufferGeometry` 是 Three.js 中一个强大的类,用于表示几何体数据。

demo案例 THREE.BufferGeometry 是 Three.js 中一个强大的类&#xff0c;用于表示几何体数据。与传统的 THREE.Geometry 类相比&#xff0c;它使用缓冲区来存储顶点数据&#xff0c;从而在性能上有显著的提升。以下是 THREE.BufferGeometry 的详细说明&#xff0c;包括其输入参…

ARM服务器在云手机中可以提供哪些支持

ARM服务器作为云手机的底层支撑&#xff0c;在很多社媒APP或者电商APP平台都有着很多看不见的功劳&#xff0c;可以说ARM扮演着至关重要的底层支持角色&#xff1b; 首先&#xff0c;ARM 服务器为云手机提供了强大的计算能力基础。云手机需要处理大量的数据和复杂的运算&#x…

Sentinel不使用控制台基于注解限流,热点参数限流

目录 一、maven依赖 二、控制台 三、基于注解限流 四、热点参数限流 五、使用JMeter验证 一、maven依赖 需要注意&#xff0c;使用的版本需要和你的SpringBoot版本匹配&#xff01;&#xff01; Spring-Cloud直接添加如下依赖即可&#xff0c;baba已经帮你指定好版本了。…

沃尔玛、美客多跨境平台自养号全攻略:防关联环境系统搭建与养号技巧

在沃尔玛、美客多等跨境平台进行自养号的过程中&#xff0c;环境系统的选择和账号的养育是至关重要的。以下是我对这两个方面的经验和技巧的总结&#xff1a; 环境系统&#xff1a; 市面上有很多环境系统可供选择&#xff0c;但质量参差不齐。为了实现足够高的伪装度&#xff…

服务器数据恢复—raid5阵列上分配的卷被删除后重建如何恢复被删除卷的数据?

服务器存储数据恢复环境&#xff1a; 某品牌FlexStorage P5730服务器存储&#xff0c;存储中有一组由24块硬盘组建的RAID5阵列&#xff0c;包括1块热备硬盘。 服务器存储故障&#xff1a; 存储中的2个卷被删除&#xff0c;删除之后重建了一个新卷。需要恢复之前删除的一个卷的数…

高舒适性气膜网球馆的注意事项—轻空间

气膜网球馆以其高舒适性、智能恒温等特点&#xff0c;成为现代体育场馆的新宠。在国家提倡全民健身的背景下&#xff0c;各地气膜网球馆如雨后春笋般涌现。然而&#xff0c;在建设和使用气膜网球馆时&#xff0c;需要特别注意以下几点&#xff1a; 1. 避免随意拆装 气膜网球馆…

Three.js——tween动画、光线投射拾取、加载.obj/.mtl外部文件、使用相机控制器

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

[数据集][目标检测]剪刀石头布检测数据集VOC+YOLO格式1973张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1973 标注数量(xml文件个数)&#xff1a;1973 标注数量(txt文件个数)&#xff1a;1973 标注…

SpringBoot接口防抖(防重复提交)

SpringBoot接口防抖&#xff08;防重复提交&#xff09; 概念 Spring Boot接口防抖&#xff08;Debouncing&#xff09;的概念是指在处理请求时&#xff0c;通过一定的机制来防止用户频繁触发同一接口请求&#xff0c;以防止重复提交或频繁请求的情况发生。 在Web应用中&…

Jupyter Notebook 切换虚拟环境

具体流程&#xff1a; 1. 查看当前jupyter notebook的环境&#xff1a; 从上面可看出当前jupyter只有一个python 3的环境。 2、 在终端中切换至想要添加的环境&#xff1a; 2.1 激活你要添加的环境 conda activate sf 2.2 在当前环境中安装ipykernel conda install ipyke…

手把手教你【如何使用Vue3+Spring Boot实现一个视频点播功能】

一、简介 本项目是一个实际的视频点播应用&#xff0c;采用了Vue3和Spring Boot作为主要技术栈。旨在帮助开发者通过学习和参考实现思路来掌握相关知识。它主要解决了阿里云视频点播服务的接入、视频基础信息管理以及上传视频后获取视频ID等关键流程&#xff0c;涉及前后端交互…