优先级队列【C++】

news2025/5/15 7:02:55

文章目录

  • priority_queue
  • priority_queue 使用
  • priority_queue的模拟实现
    • 向上调整算法
    • 向下调整算法
    • push
    • pop
    • top
    • size
    • empty
  • 仿函数
  • 完整代码

priority_queue

优先队列(priority_queue)也是队列的一种,priority_queue的接口是和queue的接口是相同的。所以两者的使用语法也是相同的。我们直接看优先队列(priority——queue)的底层实现原理。

默认情况下priority_queue是大堆。

priority_queue 使用

//用vector作为底层容器,内部构造大堆结构。
priority_queue<int, vector<int>, less<int>> q1;
//用vector作为底层容器,内部构造小堆结构。
priority_queue<int, vector<int>, greater<int>> q2;
//不指定底层容器和内部需要构造的堆结构。
priority_queue<int> q3;
#include <iostream>
#include <functional>
#include <queue>
using namespace std;
int main()
{
	priority_queue<int> q;
	q.push(3);
	q.push(6);
	q.push(0);
	q.push(2);
	q.push(9);
	q.push(8);
	q.push(1);
	while (!q.empty())
	{
		cout << q.top() << " ";
		q.pop();
	}
	cout << endl; //9 8 6 3 2 1 0
	return 0;
}

priority_queue的模拟实现

priority_queue的底层实际上就是堆,模拟实现priority_queue之前,需要知道向下调整和向上调整算法。(下面这两种算法我们均以大堆为例)

向上调整算法

向上调整算法的前提:
若想将其调整为小堆,那么根结点的左右子树必须都为小堆。
 若想将其调整为大堆,那么根结点的左右子树必须都为大堆

向堆中插入数据需要使用到向上调整算法
先将元素插入到堆的末尾,即最后一个孩子之后,从插入节点位置开始和父节点比较,(我们以大堆为例),如果目标结点的值比父结点的值大,则交换目标结点与其父结点的位置,并将原目标节点的父节点当作新的目标节点,继续向上调整,调整到根节点结束,此时该树已经是大堆了

图中是以小堆为例:
在这里插入图片描述

向下调整算法

向下调整算法的前提:
若想将其调整为小堆,那么根结点的左右子树必须都为小堆。
 若想将其调整为大堆,那么根结点的左右子树必须都为大堆

从根节点开始,选出左右孩子值较大的节点,让值较大的节点与父节点的值进行比较,如果值较大的节点比父节点的值小,交换两者位置,将原来值较大的孩子节点作为父节点,继续向下调整,调整到叶子节点结束

图中是以小堆为例:
在这里插入图片描述

push

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

pop

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

top

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

size

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

empty

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

仿函数

using namespace std;
//仿函数 /函数对象
template <class T>
class Less
{
public:
	bool operator() (const T& x, const T& y)
	{
		return x < y;
	}
};

int main()
{
	Less<int>  lessfunc;
	bool result = lessfunc(6, 2);//仿函数
	//bool result = lessfunc.operator()(6, 2);
	cout <<boolalpha <<result << endl;
	return 0;
}

完整代码

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

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

namespace cxq
{
	template<class T, class Container = vector<T>, class Compare = Less<T> >
	class priority_queue
	{
	private:
		void AdjustDown(int parent)//从根节点开始
		{
			Compare com;//仿函数
			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				//假设默认左孩子大于右孩子
			   // if (child + 1 < _con.size() && _con[child + 1] > _con[child])//右孩子要存在,防止越界
				if (child + 1 < _con.size() && com(_con[child + 1], _con[child]))
				{
					child++;
				}
				//if (_con[child] > _con[parent])
				if (com(_con[parent], _con[child]))
				{
					swap(_con[child], _con[parent]);
					int  parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}

		}
		void AdjustUp(int child)
		{
			Compare com;//仿函数
			int parent = (child - 1) / 2;
			//大堆

			while (child > 0)
			{
				//if (_con[child] > _con[parent])
				if (com(_con[parent], _con[child]))
				{
					swap(_con[child], _con[parent]);
					int child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
	public:
		//默认构造
		priority_queue()
		{}
		template<class InputIterator>
		//构造函数
		priority_queue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_con.push_back(*first);
				first++;
			}
			//建堆
			//最后一个非叶子节点
			for (size_t i = (_con.size() - 1 - 1) / 2; i >= 0; i++)
			{
				AdjustDown(i);
			}
		}
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);
		}
		void push(const T& x)
		{
			_con.push_back(x);
			AdjustUp(_con.size() - 1);
		}
		const T& top()
		{
			return _con[0];
		}
		bool empty()
		{
			return _con.empty();
		}
		bool size()
		{
			return _con.size();
		}
	private:
		Container _con;

	};
	void test_priority_queue1()
	{
		//默认是大堆--less
		//priority_queue<int> pq;
		priority_queue<int, vector<int>, Greater<int> > pq;//小堆
		pq.push(3);
		pq.push(5);
		pq.push(1);
		pq.push(4);
		while (!pq.empty())
		{
			cout << pq.top() << " ";
			pq.pop();
		}
		cout << endl;
	}
	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;
	}
	struct  LessPDate
	{
		//仿函数
		bool operator() ( const Date * p1 , const Date* p2)
		{
			return *p1 < *p2;
		}
	};
	void test_priority_queue2()
	{
		//priority_queue<Date> pq;
		//pq.push(Date(2023, 7, 20));
		//pq.push(Date(2023, 6, 20));
		//pq.push(Date(2023, 8, 20));
		//while (!pq.empty())
		//{
		//	cout << pq.top() << " ";
		//	pq.pop();
		//}
		//cout << endl;
		priority_queue<Date*, vector<Date*>, LessPDate> pq;
		pq.push(new Date(2023, 7, 20));
		pq.push(new Date(2023, 6, 20));
		pq.push(new Date(2023, 8, 20));
		while (!pq.empty())
		{
			cout << *pq.top() << " ";
			pq.pop();
		}
		cout << endl;
	}
	
}

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

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

相关文章

一篇文章了解Java spring中bean的生命周期!

一.介绍在Java spring中bean的生命周期 1.什么是 Bean&#xff1f; 我们来看下 Spring Framework 的官方文档&#xff1a; In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean …

xcode14.3更新一系列问题

1. Missing file libarclite_iphoneos.a (Xcode 14.3) 解决方法 Xcode升级到14.3后编译失败&#xff0c;完整错误日志&#xff1a; File not found: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneo…

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 cv2.grabCut(img: Mat, mask: typing.Optional[Mat], rect, bgdModel, fgdModel, iterCount, mode…) img…

linux训练深度学习模型:文件基本操作

解压.zip unzip XXX.zip 创建目录&#xff1a; mkdir data 在当前目录下创建下一级目录 移动文件&#xff1a; mv /data1/census.csv /data1/data 要写全目录路径&#xff0c;不然会跑到根目录那里去。 复制文件到当前目录下&#xff0c;并重命名 cp main.py ./main…

CSS基础 知识点总结

一.CSS简介 1.1 CSS简介 ① CSS指的是层叠样式表&#xff0c;用来控制网页外观的一门技术 ② CSS发展至今&#xff0c;经历过CSS1.0 CSS2.0 CSS2.1 CSS3.0这几个版本&#xff0c;CSS3.0是CSS最新版本 1.2 CSS引入方式 ① 在一个页面引入CSS&#xff0c;共有三种方式 外部…

《一个操作系统的实现》windows用vm安装CentOS——从bochs环境搭建到第一个demo跑通

vm安装CentOS虚拟机带有桌面的版本。su输入密码123456。更新yum -y update 。一般已经安装好后面这2个工具&#xff1a;yum install -y net-tools wget。看下ip地址ifconfig&#xff0c;然后本地终端连接ssh root192.168.249.132输入密码即可&#xff0c;主要是为了复制网址方便…

基于SOLIDWORKS配置功能建立塑料模具标准件库

在塑料模具的设计过程中&#xff0c;建立其三维模型对于后续进行CAE分析和CAM加工是非常重要的。除了型腔和型芯以外&#xff0c;塑料模具中的标准件很多&#xff0c;如推杆、导柱、导套、推板、限位钉等&#xff0c;这些对于不同的产品是需要反复调用的。目前&#xff0c;我国…

GWAS-eQTL colocalization analysis workflow

1. The purpose of GWAS-eQTL intergration Is the my variant an eQTL?Is the leading variant of the GWAS and eQTL signal the same?Is my GWAS association of interest driven by an eQTL that may indiciate a functinal mechanism? GWAS locus that colocalized w…

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/

IntelliJ IDEA 官方网站 idea官网 http://www.jetbrains.com/idea/ Idea下载官网一键直达&#xff1a; 官网一键直达

低代码揭秘:企业开发能力提升的秘诀!

从捷码官网获取的捷码产品体验账号&#xff0c;用浏览器打开下列地址即可&#xff08;推荐电脑端哈&#xff09;&#xff0c;需要自取&#xff1a; http://dev.gemcoder.com/front/development/index.html#/officialLogin?jmcmVnaXN0ZXI9dHJ1ZQ%3D%3D 对于很多软件开发企业来说…

北京筑龙智能物料:企业供应链数字化转型新思路

8月16-18日&#xff0c;由中国物流与采购联合会主办的“2023&#xff08;第十五届&#xff09;物流与供应链数字化发展大会”在贵州省贵阳市召开。北京筑龙智能化事业部总经理、筑龙研究院副院长胡婧玥受邀出席&#xff0c;带来主题为“智能物料——企业供应链数字化转型新思路…

Windows定时任务计划无法显示任务程序界面的问题解决

笔者这两天写了一个python脚本程序&#xff0c;用来自动从公司的主数据系统获取数据&#xff0c;并按格式编制成excel。脚本程序编写一切顺利&#xff0c;运行结果很是完美&#xff0c;笔者很是舒心。但在最后一步&#xff0c;用上班的电脑每天早上定时运行它时&#xff0c;出了…

msvcp110.dll丢失原因,msvcp110.dll丢失修复方法

装好软件或游戏之后&#xff0c;一打开就跳出各种报错信息的情况小伙伴一定见过&#xff0c;其中缺少各种msvcp110.dll文件最常见。小伙伴们一定奇怪&#xff0c;用得好好的电脑&#xff0c;怎么会缺文件呢&#xff1f;为啥其他游戏/应用就没事呢&#xff1f;其实这些“丢失”的…

Python OpenGL环境配置

1.Python的安装请参照 Anconda安装_安装anconda_lwb-nju的博客-CSDN博客anconda安装教程_安装ancondahttps://blog.csdn.net/lwbCUMT/article/details/125322193?spm1001.2014.3001.5501 Anconda换源虚拟环境创建及使用&#xff08;界面操作&#xff09;_anconda huanyuan_l…

数据库索引优化策略与性能提升实践

文章目录 什么是数据库索引&#xff1f;为什么需要数据库索引优化&#xff1f;数据库索引优化策略实践案例&#xff1a;索引优化带来的性能提升索引优化规则1. 前导模糊查询不适用索引2. 使用IN优于UNION和OR3. 负向条件查询不适用索引4. 联合索引最左前缀原则5. 范围条件查询右…

回到未来:使用马尔可夫转移矩阵分析时间序列数据

一、说明 在本文中&#xff0c;我们将研究使用马尔可夫转移矩阵重构时间序列数据如何产生有趣的描述性见解以及用于预测、回溯和收敛分析的优雅方法。在时间上来回走动——就像科幻经典《回到未来》中 Doc 改装的 DeLorean 时间机器一样。 注意&#xff1a;以下各节中的所有方程…

用KMP的方法解决《重复的子字符串》

提出问题 给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 示例 1: 输入: “abab” 输出: True 解释: 可由子字符串 “ab” 重复两次构成。 示例 2: 输入: “aba” 输出: Fa…

eqtl-GWAS和GWAS-GWAS

目前教程中有eqtl-GWAS和GWAS-GWAS两种模式&#xff0c;其他模式比较少见&#xff0c;还未进行开发 数据类型cc为分类变量即case/control&#xff0c;quant为连续变量&#xff0c;eqtl数据默认quant coloc.abf有两个比较需要注意的点&#xff0c;就是数据集中N是代表样本量&am…

你真的了解你的交易吗?不妨了解下KYT

作者&#xff5c;Jason Jiang 随着行业高速发展与监管持续关注&#xff0c;虚拟资产领域正加速迈入合规时代。为应对虚拟资产的链上洗钱风险&#xff0c;欧科云链此前推出了Onchain AML合规技术方案&#xff0c;以助力行业健康有序发展。在Onchain AML反洗钱方案中&#xff0c;…

c++游戏制作指南(四):c++实现数据的存储和读取(输入流fstream)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到静渊隐者的csdn博文&#xff0c;本文是c游戏制作指南的一部&#x1f35f; &#x1f355;更多文章请点击下方链接&#x1f355; &#x1f368; c游戏制作指南&#x1f3…