【C++进阶专栏】:priority_queue(优先级队列)?仿函数?

news2024/10/24 11:15:46

在这里插入图片描述

文章目录

  • 前言
    • 1、优先级队列的使用?
    • 2、仿函数?
    • 3、优先级队列用仿函数实现大/小堆变换?

前言

priority_queue:优先级队列,别看有一个队列的名字,但结构个队列完全不一样。队列是一种先进先出的结构特征,然而这里的优先级队列,此结构是一种堆的结构,但是用vector形式存储数据的。以堆的结构来实现该优先级队列,可以在每次top堆顶元素的时候都是最大或最小的元素,可以应用于top_k问题,即返回一个大量数据中前K个较大的元素值。接下来就来了解了解优先级队列吧!

1、优先级队列的使用?

对优先级队列的插入、删除、判空等函数的使用。

#include<iostream>
#include<queue>
using namespace std;

//优先级的队列头文件就是queue
void test()
{
	priority_queue<int> pq;
	pq.push(10);
	pq.push(66);
	pq.push(1);
	pq.push(6);
	pq.push(12);
	pq.push(87);
	pq.push(45);
	pq.push(23);
	cout << "优先级队列的数据个数:" << pq.size() << endl;
	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
}

int main()
{
	test();
	return 0;
}

在这里插入图片描述

输出结构就是从大到小的,因为默认是建立的大堆。
在这里插入图片描述
传入的是less(仿函数),就是插入的数据小于父节点就上调的,从而建立大堆。然后依次top堆顶元素就是大的数据。

2、仿函数?

仿函数实质是一个类,是一个什么类呢?
是一种重载了函数调用运算符operator()的类或结构体,它可以使一个类的使用看上去像一个函数。仿函数可以接受参数并返回值,可以用于STL算法中的函数对象参数,也可以用于函数指针的替代。

仿函数的主要作用包括:
‌①提供一种灵活的方式来实现函数对象‌,可以根据实际需求定制自己的函数对象,比如排序、查找等算法。
‌②封装函数参数‌,使得算法可以接受不同类型的参数,增加算法的通用性。
③保存状态‌,在多次调用之间保持状态,避免每次调用时都需要重新计算。
‌④替代函数指针‌,因为函数指针只能指向全局函数或静态成员函数,而仿函数可以指向任意类型的函数,包括成员函数和非静态成员函数。

下面是一个仿函数的例子:

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;
	}
};

template<class T,class Compare>
void BubbleSort(vector<T>& v,Compare com)
{
	int i = 0, j = 0;
	for (i = 0; i < v.size(); i++)
	{
		int flag = 0;
		for (j = 1; j < v.size() - i; j++)
		{
			if (com(v[j], v[j - 1]))
			{
				swap(v[j-1],v[j]);
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;
		}
	}
}

int main()	
{
	vector<int> v;
	v.push_back(5);
	v.push_back(7);
	v.push_back(8);
	v.push_back(1);
	v.push_back(0);
	v.push_back(2);
	v.push_back(6);
	v.push_back(9);
	
	BubbleSort(v, Less<int>());//此处是匿名对象传参的,也可以先创建Less less;
	auto it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	
	return 0;
}

在这里插入图片描述
结果就是一个升序:
在这里插入图片描述

3、优先级队列用仿函数实现大/小堆变换?

首先要知道优先级队列是使用vector容器存储数据,结构上是堆。默认是建大堆。

实现思路:
①插入函数:每当插入一个数据,就向上调整,保证每插入一个数据依然是大堆。
②删除函数:不是直接删除堆顶元素,而是先交换堆顶元素和末尾元素。然后直接删除最后一个数据,之后再做向下调整。
③返回top元素:由于是vector容器存储的数据,即直接返回下标为0的数据即可。
④求数据个数:直接调用size()函数
⑤判空:直接调用vector的empty()函数。

#pragma once

namespace zc
{
	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;
		}
	};

	//template<class T,class Container=std::vector<T>>
	template<class T, class Container = std::vector<T>,class Compare=Less<int>>
	class Prority_queue
	{
	private:
		//向上调整算法
		void AdjustUp(size_t child)
		{
			//先计算父节点
			size_t parent = (child - 1) / 2;
			//调整
			while (child > 0)
			{
				//判断,若孩子比父亲的值大,则交换
				//if (_con[child] > _con[parent])
				if (com(_con[parent],_con[child]))

				{
					std::swap(_con[child], _con[parent]);
					//重新找父节点
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		
		//向下调整函数
		void AdjustDown(int parent)
		{
			//计算孩子,由于要找大的数据,因此假设左孩子数据更大
			int child = parent * 2 + 1;
			//然后调整,直到孩子节点大于或等于数据个数
			while (child < _con.size())
			{
				//判断和右孩子谁大
				//if (child+1<_con.size()&&_con[child] < _con[child + 1])
				if (child + 1 < _con.size() && com(_con[child] , _con[child + 1]))
				{
					child += 1;//变为右孩子的位置
				}

				//if (_con[parent] < _con[child])
				if (com(_con[parent] , _con[child]))
				{
					std::swap(_con[parent],_con[child]);
					//更新
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

	public:
		//先写插入函数
		void push(const T&  x)
		{
			_con.push_back(x);
			//插入以后向上调整见大堆,从刚插入的位置开始调整
			AdjustUp(_con.size()-1);
		}

		//删除函数
		void pop()
		{
			//先交换堆顶元素和末尾的元素,再删除最后的一个元素
			std::swap(_con[0],_con[_con.size()-1]);
			_con.pop_back();
			//再向下调整
			AdjustDown(0);
		}

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

		//计算大小
		size_t size()const
		{
			return _con.size();
		}
		//判断是否为空
		bool empty()const
		{
			return _con.empty();
		}

	private:
		Container _con;
		Compare com;
	};
}

#include<iostream>
#include"PriorityQueue.h"

//自定义优先级队列
void test_06()
{
	//zc::Prority_queue<int> pq;
	//zc::Prority_queue<int> pq;//缺省值是vector<int>,Less<int>
	zc::Prority_queue<int,std::vector<int>,zc::Greater<int>> pq;
	pq.push(14);
	pq.push(20);
	pq.push(45);
	pq.push(3);
	pq.push(10);
	pq.push(66);
	pq.push(1);
	pq.push(0);
	std::cout << "自定义优先级队列数据个数:" << pq.size() << std::endl;
	while (!pq.empty())
	{
		std::cout << pq.top() << " ";
		pq.pop();
	}
}

int main()
{
	std::cout << "自定义的优先级队列:" << std::endl;
	test_06();
	std::cout << std::endl;

	return 0;
}

比较大于:即升序这里是引用
比较小于:降序
在这里插入图片描述

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

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

相关文章

AttributeError: ‘str‘ Object Has No Attribute ‘x‘:字符串对象没有属性x的完美解决方法

AttributeError: str Object Has No Attribute x&#xff1a;字符串对象没有属性x的完美解决方法 &#x1f50d;&#x1f4a1; AttributeError: str Object Has No Attribute x&#xff1a;字符串对象没有属性x的完美解决方法 &#x1f50d;&#x1f4a1;摘要 &#x1f4d6;引言…

四、音频播放

一、相关逻辑 在登录代码中调用&#xff0c;资源加载代码&#xff0c;然后再资源加载代码中调用。 1、登陆方法中&#xff1a; 单例类音频调用自己的方法&#xff0c;然后传入配置代码中的常量 2、音频播放代码中&#xff1a; 首先设置为一个单例类&#xff0c;然后初始化一…

精益与数字化的融合:制造业的创新之路

回望过去&#xff0c;精益管理作为制造业的瑰宝&#xff0c;以其“消除浪费、持续改进、顾客至上”的核心理念&#xff0c;引领了无数企业走向成功。从丰田生产方式到全球范围内的广泛实践&#xff0c;精益管理不仅提升了生产效率&#xff0c;更重塑了企业的文化和价值观。它教…

【Python大语言模型系列】一文教你使用dify云版本开发一个简单的Agent(完整教程)

这是我的第365篇原创文章。 一、引言 智能助手&#xff08;Agent&#xff09;&#xff0c;利用大语言模型的推理能力&#xff0c;能够自主对复杂的人类任务进行目标规划、任务拆解、工具调用、过程迭代&#xff0c;并在没有人类干预的情况下完成任务。 本文我们将搭建一个旅行…

vt虚拟化怎么开启_各品牌主板及品牌机开启VT虚拟化教程

VT指的是CPU的虚拟化技术可以单CPU模拟多CPU并行&#xff0c;允许一个平台同时运行多个操作系统&#xff0c;并且应用程序都可以在相互独立的空间内运行而互不影响&#xff0c;从而显著提高计算机的工作效率。下面&#xff0c;小编给大家介绍电脑开启vt的操作步骤。 VT虚…

[LeetCode] 155. 最小栈

设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int get…

TiDB 监控组件之 Blackbox_exporter 运行原理

作者&#xff1a; TiDBerHailang 原文来源&#xff1a; https://tidb.net/blog/b269e96f 1. 介绍 本文介绍了 TiDB 集群监控组件Blackbox Exporter监控运行机制和配置方式。Blackbox Exporter是Prometheus官方提供的 Exporter&#xff0c;它能够通过多种协议对网络服务进行…

使用HTML、CSS和JavaScript创建滚动弹幕效果

使用HTML、CSS和JavaScript创建滚动弹幕效果 在现代网页设计中&#xff0c;滚动文本是一种常见的动态效果&#xff0c;可以吸引用户的注意力并增强交互体验。在这篇博客文章中&#xff0c;我们将详细介绍如何使用HTML、CSS和JavaScript实现滚动文本效果。 效果 步骤1&#xf…

【电商购物管理系统】Python+Django网页界面平台+商品管理+数据库

一、介绍 电商购物管理系统&#xff0c;本系统前端使用HTML、CSS、BootStrap等技术搭建前端界面&#xff0c;后端使用Django框架处理用户的逻辑请求。主要功能有&#xff1a; 管理员登录与管理&#xff1a;管理员可以登录后台&#xff0c;对用户和商品进行增删改查的操作。用…

使用mybatis查询数据库时,表有数据但是为空值null

前言 数据库有数据但是查出来都是空的 解决方法 这里写错了&#xff0c; resultType只能用在数据库字段和实体类字段一致的情况下&#xff0c;而数据库多单词通常用下划线隔开&#xff0c;不能映射到驼峰命名的实体类属性上&#xff0c;因此得使用一个ResultMap 1.定义映射映…

【C++】set/map(重点解析)

目录 一、关联式容器和序列式容器 二、C中的键值对——pair 1.概念 2.定义 3.构造pair 三.set 1.construct构造 2.iterator迭代器 3.insert插入 4.erase删除 5.find查找 6.lower_bound和upper_bound 7.count 四.multiset 五.map 1.insert 2.operator[] 一、…

Pygame实现音乐可视化

pip install pydub pip install ffmpeg pip install pyaudio 完整代码如下&#xff1a; import pygame,sys import random import numpy as np from random import randint import colorsys from pydub import AudioSegment import mathdef rnd_color(): #随机颜色h,s,l…

Python的reshape的用法和reshape(1,-1)、reshape(-1,1)

在创建DataFrame的时候常常使用reshape来更改数据的列数和行数。 reshape可以用于numpy库里的ndarray和array结构以及pandas库里面的DataFrame和Series结构。 reshape&#xff08;行&#xff0c;列&#xff09;可以根据指定的数值将数据转换为特定的行数和列数&#xff0c;这个…

用SAM2和Cutie模型目标追踪

一、数据集 视频&#xff1a;每个视频文件夹以图片帧的形式存储 box&#xff1a;给出每个视频第一帧要追踪的物体的box 二、将数据格式转换成SAM2所需要的格式 主要是将box转换成mask的格式&#xff0c;下面这个代码就是将box转换成mask的代码&#xff0c;具体转换原理如下…

深圳易图讯科技有限公司承建的厦门应急处突大队三维电子沙盘顺利通过专家验收

近日&#xff0c;深圳易图讯科技有限公司承建的厦门应急处突大队三维电子沙盘系统项目成功通过专家组的严格验收&#xff0c;标志着该系统在应急管理和处置突发事件方面的应用取得了重要突破。 验收过程中&#xff0c;专家组对三维电子沙盘系统的各项功能进行了全面而细致的测试…

第十六周:机器学习笔记

第十六周周报 摘要Abstratc一、机器学习1. Pointer Network&#xff08;指针网络&#xff09;2. 生成式对抗网络&#xff08;Generative Adversarial Networks | GAN&#xff09;——&#xff08;上&#xff09;2.1 Generator&#xff08;生成器&#xff09;2.2 Discriminator&…

Cef加载自定义本地资源

在Cef auto build下载cefCEF Automated Builds 我下载的是104&#xff0c;使用cefsimple工程。 例如&#xff1a;前端资源如下 通过http协议把前端资源加载出来。所有的资源都通过http://local.test.cn/xxx加载。 前端资源包括index.html、test.css、test.js index.html&am…

麒麟系统离线安装英伟达驱动

麒麟系统离线安装英伟达驱动 驱动相关程序下载下载显卡驱动下载CUDA-Toolkit下载cudnn 安装关闭自带图形界面禁用 Nouveau 驱动安装驱动安装CUDA-Toolkit安装cudnn 驱动相关程序下载 下载显卡驱动 进入显卡驱动查询页面&#xff0c;下载对应的显卡驱动&#xff0c;页面如下&a…

第十节:React路由:react-router认识与基本使用

1. React Router的理解 React的路由根据项目的不同使用不同的路由库,web应用主要使用react-router和react-router-dom react-router和react-router-dom的区别 react-rotuer 核心库,提供了一些核心的api,但是没有提供dom操作进行跳转的api react-router-dom扩展了核心库,提供了一…

Edge TTS

edge-tts项目地址&#xff1a;https://github.com/rany2/edge-tts 1.安装部署 在cmd中运行以下命令安装edge-tts pip install edge-tts pip install edge-tts速度非常快&#xff0c;几秒钟就安装完成了。 2.文本转语音 输入以下命令&#xff0c;将一段英文转为音频。 edg…