【C++】priority_queue(优先级队列介绍、仿函数控制大堆小堆、模拟实现)

一、优先级队列

1.1介绍

优先级队列(Priority Queue)是一种特殊的数据结构,其并不满足队列先进先出的原则,它结合了队列和堆的特点,允许我们在其中插入元素,并且能够保证任何时候提取出的元素都是当前队列中具有最高(或最低)优先级的元素。在优先级队列中,每个元素都有一个关联的优先级值,这个值通常用于决定元素在队列中的相对位置。

基本特性:

  1. 插入(Enqueue):可以向优先级队列中添加元素,新元素会被放置在正确的位置以保持队列的优先级特性。

  2. 删除(Dequeue/Peek):从优先级队列中删除或查看优先级最高的元素(如果是最大优先级队列)或最低的元素(如果是最小优先级队列)。这一操作也称为取队首元素,但在优先级队列中,队首元素并不总是最先入队的元素,而是优先级最高的元素。

  3. 排序性质:优先级队列内的元素始终按照优先级排序,这意味着即使新元素不断加入,队列仍然能快速提供最高(或最低)优先级的元素。

优先级队列是一种非常实用的数据结构,适用于那些需要高效处理动态优先级数据的场景,它可以灵活地满足按照优先级而非简单时间顺序处理数据的需求。

1.2 使用介绍

定义:
template <class T, class Container = vector<T>, class Compare = less<T> >
class priority_queue

解释:

  • T为数据的类型
  • Container为容器适配器的类型,缺省值为vector<T>,也可以显示传queue等用数组实现的容器
  • Compare是用来控制大小堆的,缺省值为less<T>为大堆,也可以传greater<T>,less与greater都是仿函数
常用接口:
函数声明 接口说明
prioprity_queue()构造一个空的优先级队列
empty()检测优先级队列是否为空,是返回true,否则返回 false
top()返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素
代码示例:
#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
 
void TestPriorityQueue()
{
 // 默认情况下,创建的是大堆,其底层按照小于号比较
 vector<int> v{3,2,7,6,0,4,1,9,8,5};
 priority_queue<int> q1;
 for (auto& e : v)
 q1.push(e);
 cout << q1.top() << endl;
 
 // 如果要创建小堆,将第三个模板参数换成greater比较方式
 priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
 cout << q2.top() << endl;
}

 二、priority_queue模拟实现及仿函数讲解

1. 结构
    template<class T,class Container=vector<T>,class Cmp=Less<T>>
	class priority_queue
	{
	private:
		Container _con;//容器
		Cmp _cmp;//仿函数对象
	};
2.仿函数

仿函数是指一类特殊的类,这类类通过在其内部重载operator()运算符,使得该类的对象可以像普通函数一样被调用。当对仿函数对象进行“函数调用”时,实际上执行的是operator()成员函数。在向上调整与向下调整时,需要一个方式来如何比较大小,也就是控制大小堆,这个功能可以使用函数指针来实现,但C++更偏向于使用仿函数

注意如果要将自定义类型放入priority_queue中的话,一定要在自定义类型中重载<或者>

3.push

将数据插入容器尾部,通过向上调整法调整到合适位置

    void push(const T& x)
    {
	    _con.push_back(x);
	    adjustUp(_con.size()-1);
    }
    //向上调整算法
    void adjustUp(size_t child)
	{
		int parent = (child - 1) / 2;
		while (child > 0)
		{
            //利用仿函数比较
			if (_cmp(_con[parent], _con[child]))
			{
				swap(_con[parent], _con[child]);
				child = parent;
				parent = (parent - 1) / 2;
			}
			else
			{
				break;
			}
		}
	}
4.pop

交换交换堆顶与堆尾的元素,删除堆尾元素,并将堆头元素向下调整到合适位置

    void adjustDown(size_t parent)
	{
		size_t child = parent * 2 + 1;
		while (child<_con.size())
		{
			if (child+1 < _con.size( )&& _cmp(_con[child], _con[child + 1]))
			{
				child++;
			}

			if (_cmp(_con[parent],_con[child]))
			{
				swap(_con[parent], _con[child]);
				parent = child;
				child = child * 2 + 1;
			}
			else
			{
				break;
			}
		}
	}
	void pop()
	{
		swap(_con[0], _con[_con.size() - 1]);
		_con.pop_back();
		adjustDown(0);
	}
5.empty
    bool empty()
	{
		return _con.empty();
	}
6.size
    const size_t size() const
	{
		return _con.size();
	}
7.top
    const T& top() const
	{
		return _con[0];
	}

完整代码:

#include<vector>
using namespace std;
namespace zyq
{
	template<class T,class Container=vector<T>,class Cmp=Less<T>>
	class priority_queue
	{
	public:
		void adjustUp(size_t child)
		{
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				 if (_cmp(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (parent - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

		void adjustDown(size_t parent)
		{
			size_t child = parent * 2 + 1;
			while (child<_con.size())
			{
				if (child+1 < _con.size( )&& _cmp(_con[child], _con[child + 1]))
				{
					child++;
				}

				if (_cmp(_con[parent],_con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = child * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void push(const T& x)
		{
			_con.push_back(x);
			adjustUp(_con.size()-1);
		}
		
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjustDown(0);
		}
		
		bool empty()
		{
			return _con.empty();
		}

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

		const T& top() const
		{
			return _con[0];
		}
	private:
		Container _con;
		Cmp _cmp;
	};

	template<class T>
	struct Less
	{
		bool operator()(const T& a, const T& b)
		{
			return a < b;
		}
	};

	template<class T>
	struct Greater
	{
		bool operator()(const T& a, const T& b)
		{
			return a > b;
		}
	};
}

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

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

相关文章

有公网IP,如何设置端口映射实现访问?

很多中小型公司或个人会根据自身需求自建服务器&#xff0c;或者将自己内网的服务、应用发布到外网&#xff0c;实现异地访问&#xff0c;如远程桌面、网站、数据库、公司的管理系统、FTP、管家婆、监控系统等等。 没接触过的人可能会觉得这个很难&#xff0c;实际上使用快解析…

【 书生·浦语大模型实战营】学习笔记(五):LMDeploy 量化部署

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

【机器学习】特征筛选:提升模型性能的关键步骤

一、引言 在机器学习领域&#xff0c;特征筛选是一个至关重要的预处理步骤。随着数据集的日益庞大和复杂&#xff0c;特征的数量往往也随之激增。然而&#xff0c;并非所有的特征都对模型的性能提升有所贡献&#xff0c;有些特征甚至可能是冗余的、噪声较大的或者与目标变量无关…

2024/4/22(分布式服务事务,CAP,BASE理论,Seata,微服务集成Seata,XA,AT,TCC.Saga,TC高可用,异地容灾)

配置内容如下&#xff1a;properties # 数据存储方式&#xff0c;db代表数据库 store.modedb store.db.datasourcedruid store.db.dbTypemysql store.db.driverClassNamecom.mysql.jdbc.Driver store.db.urljdbc:mysql://127.0.0.1:3306/seata?useUnicodetrue&rewriteBatc…

鸿蒙TypeScript学习21天:【声明文件】

TypeScript 作为 JavaScript 的超集&#xff0c;在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法&#xff0c;但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题&#xff0c;需要将这些库里的函数和方法体去…

Python多线程与多进程编程

一、引言 随着计算机技术的飞速发展&#xff0c;程序运行的速度和效率成为了人们关注的焦点。为了提高程序的执行效率&#xff0c;多线程与多进程编程技术应运而生。Python作为一种通用编程语言&#xff0c;在支持多线程与多进程编程方面有着独特的优势。本文将详细探讨Python…

截断堆积柱状图

本教程原文链接&#xff1a;截断堆积柱状图绘制教程 欢迎大家转载&#xff01;&#xff01;&#xff01;&#xff01; 本期教程 写在前面 堆积柱状图是柱状图的常见类型之一&#xff0c;也是平时使用概率较高的图形之一。我们前期发布了很多个柱状图的绘制教程&#xff0c;若你…

DBUnit增强:填充随机数据和相对时间数据

痛点 测试环境验证时&#xff0c;遇到与当前相对时间相关的测试吗&#xff1f;准备一份SQL&#xff1f;隔一段时间就不能用了。每过一段时间去更新脚本或重置系统时间&#xff1f;看上去也不是很合适的解决方案。依赖数据测试时要重新做&#xff0c;演示时候得全部改&#xff…

用两种方式遍历Map集合

创建学生类对象 public class Student {private String name;public int age ;public Student() {}public Student(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}publi…

LINUX核心配置文件md5监控

一、md5sum简介 md5sum 用于计算和校验文件的MD5值。 md5sum 常常被用来验证网络文件传输的完整性&#xff0c;防止文件被人篡改。在日常工作当中&#xff0c;我们可以用来判断系统中的重要文件是否被篡改。传文件给别人时确认是否一致。我们也还可使用 md5sum 生成文件或用户…

学习笔记:Vue2中级篇

Vue2 学习笔记&#xff1a;Vue2基础篇_ljtxy.love的博客-CSDN博客学习笔记&#xff1a;Vue2中级篇_ljtxy.love的博客-CSDN博客学习笔记&#xff1a;Vue2高级篇_ljtxy.love的博客-CSDN博客 Vue3 学习笔记&#xff1a;Vue3_ljtxy.love的博客&#xff09;-CSDN博客 文章目录 5.…

电脑监控软件员工会不会发现

电脑监控软件员工会不会发现 企业在安装电脑监控软件的时候都会问一个问题&#xff1a;会不会被员工发现&#xff1f;基本上是不会被发现的&#xff0c;因为监控软件都有隐藏功能&#xff0c;比如这款安企神。&#xff08;点击免费试用&#xff09; 它在终端安装的时候为静默安…

澳福一篇文章盘点持仓交易

什么是持仓交易&#xff0c;有什么优缺点&#xff0c;收益率是多少&#xff1f;今天澳福外汇一篇文章讲清楚。 持仓交易是长期策略。它基于波浪理论&#xff0c;根据该理论&#xff0c;市场以周期性方式发展:任何增长都伴随着衰退。交易者建立长期头寸&#xff0c;从价格上涨或…

【继承】复杂的菱形继承

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C进阶 本篇文章主要讲解 菱形继承 的相关内容 目录 1. 继承与友元 2. 继承与静态成员 3. 复杂的菱形继承及菱形虚拟继承 3.1 继承分类 3.2 菱形继承导致的问题 3.3 虚拟继承解决数据冗余的原理 4. 继承和组…

揭秘链动3+1商业模式:打造未来商业新风潮

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是链动31模式&#xff1f; 在当今商业世界中&#xff0c;随着科技的飞速发展和消费者需求的不断升级&#xff0c;新的商业模式不断涌现。其中&a…

CAPL编程基础

1.程序结构 1.includes{} //头文件 2.variables{} //全局变量声明 3. on preStart{} //初始化 on start{} //工程运行 on preStop{} //工程预停止 on stopMeasurement{} //工程停止 4.int myFunction{} //自定义函数 2.事件 1.键盘事件 on key ‘a’ 2.报…

【漏洞复现】Linksys RE7000无线扩展器 命令注入漏洞(CVE-2024-25852)

0x01 产品简介 Linksys RE7000无线扩展器是一款功能强大、操作便捷的产品,旨在为用户提供无缝的网络覆盖和更快速、更稳定的网络连接体验。 0x02 漏洞概述 Linksys RE7000无线扩展器存在命令注入漏洞,未授权的攻击者可以通过该漏洞执行任意命令,控制服务器。 0x03 测绘语…

《论文阅读》对话推理的对比学习 EMNLP 2023

《论文阅读》对话推理的对比学习 前言名词简介CICERO 数据集方法损失函数实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Contrastive Learning for Inference in Dialogue》 出版:EMNLP 时…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

8-云原生监控体系-PromQL-函数

Prometheus支持几个函数来操作数据。 文章目录 1. 函数语法解释2. count(v instant-vector)3. topk(n, v instant-vector)4. bottomk(n, v instant-vector)5. increase(v range-vector)6. rate(v range-vector)7. rate 和 increase8. irate(v range-vector)9. predict_linear(…