【STL】priority_queue(优先级队列)详解及仿函数使用(附完整源码)

news2024/11/17 17:43:30

目录

      • 1. priority_queue介绍和使用
        • 1.1 priority_queue介绍
        • 1.2 priority_queue使用
      • 2. 仿函数介绍
      • 3. priority_queue模拟实现

1. priority_queue介绍和使用

1.1 priority_queue介绍

优先级队列也是在<queue>里:
在这里插入图片描述

因此和queue一样,priority_queue也是一个容器适配器。priority_queue官方文档

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
    empty():检测容器是否为空
    size():返回容器中有效元素个数
    front():返回容器中第一个元素的引用
    push_back():在容器尾部插入元素
  5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
  6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。
1.2 priority_queue使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。
在这里插入图片描述

下面我们来简单验证一下:
在这里插入图片描述

那如果我们想实现小堆呢,这里就要用到仿函数:
在这里插入图片描述
在这里插入图片描述

2. 仿函数介绍

在这里插入图片描述
仿函数是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;
    }
};

这就是一个函数调用。当然本质是调用了类里面的operator()。

3. priority_queue模拟实现

#include<vector>
#include<iostream>
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 w
{


	template<class T, class Container = vector<T>, class Comapre = less<T>>
	class priority_queue
	{
	private:
		void AdjustDown(int parent)
		{
			Comapre com;

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

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

		void AdjustUp(int child)
		{
			Comapre com;

			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (com(_con[parent],_con[child]))
				{
					swap(_con[child], _con[parent]);
					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 (int 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();
		}

		size_t size()
		{
			return _con.size();
		}
	private:
		Container _con;
	};

	void test_priority_queue1()
	{
		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*, 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/1125195.html

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

相关文章

java头歌-java中的异常

文章目录 第一关第二关第三关第四关 第一关 第二关 题目要求&#xff1a; public static void main(String[] args) {Scanner sc new Scanner(System.in);try {int num1 sc.nextInt();int num2 sc.nextInt();/********* Begin *********/System.out.println(num1/num2);}…

基于stm32控制的4G模块在设备模式下通讯

这里的32控制其实和51的控制思路都是一样的&#xff0c;都是先利用一个网络助手将家里的无线网生成局域网&#xff0c;接着通过花生壳软件将局域网变成公共网&#xff0c;最后是利用串口助手&#xff0c;在4G模块的AT指令模式写入命令ATSOCKTCPC,公共网IP地址,公共网端口号&…

对话销售易CEO史彦泽:中国SaaS企业,利润和现金流从何而来?

导读&#xff1a;SaaS企业如何快速转身&#xff0c;活下来 “华为应改变思路和经营方针&#xff0c;从追求规模转向追求利润和现金流&#xff0c;保证渡过未来三年的危机。把活下来作为最主要纲领&#xff0c;边缘业务全线收缩和关闭&#xff0c;把寒气传递给每个人。” 2022年…

Pinia入门

1. 什么是Pinia Pinia 是 Vue 的专属的最新状态管理库 &#xff0c;是 Vuex 状态管理工具的替代品 2. 手动添加Pinia到Vue项目 后面在实际开发Vue医疗项目的时候&#xff0c;Pinia可以在项目创建时自动添加&#xff0c;现在我们初次学习&#xff0c;从零开始&#xff1a; …

Object.getPrototypeOf()

1、作用 获取指定对象的原型&#xff08;内部​​[[Prototype]]​​属性的值&#xff09;&#xff0c;如果没有继承属性&#xff0c;则返回 null function Animal() {}var ani new Animal();console.log(ani);console.log(Object.getPrototypeOf(ani));2、注意 在 ES5 中&a…

Http长连接同一个socket多个请求和响应如何保证一一对应?

HTTP/2引入二进制数据帧和流的概念&#xff0c;其中帧对数据进行顺序标识&#xff0c;如下图所示&#xff0c;这样浏览器收到数据之后&#xff0c;就可以按照序列对数据进行合并&#xff0c;而不会出现合并后数据错乱的情况。同样是因为有了序列&#xff0c;服务器就可以并行的…

视频去噪网络BSVD的实现

前些天写了视频去噪网络BSVD论文的理解&#xff0c;详情请点击这里&#xff0c;这两个星期动手实践了一下&#xff0c;本篇就来记录一下这个模型的实现。 这个网络的独特之处在于&#xff0c;它的训练和推理在实现上有所差别。在训练阶段&#xff0c;其使用了TSM&#xff08;T…

中国象棋棋盘识别

当象棋爱好者在挑战中国象棋残局或者在阅读象棋杀法书籍的时候遇到问题&#xff0c;往往需要通过象棋软件来辅助提示&#xff0c;此时要将该棋局在象棋软件中摆好&#xff0c;软件才能进行分析&#xff0c;为实现自动识别棋局图片&#xff0c;并导出为标准化FEN象棋文件格式&am…

Lec08 Page faults笔记总结

当一个用户应用程序触发了page fault&#xff0c;page fault会使用与Robert教授上节课介绍的相同的trap机制&#xff0c;将程序运行切换到内核&#xff0c;同时也会将出错的地址存放在STVAL寄存器中。 在SCAUSE&#xff08;注&#xff0c;Supervisor cause寄存器&#xff0c;保…

MyBatis-Plus实现逻辑删除[MyBatis-Plus系列] - 492篇

历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 M…

[Spring] SpringBoot2 简介(二)—— 高级配置

目录 一、Conditional 注解 1、SpringBoot 如何获取 Bean 对象 2、SpringBoot 创建 Condition 类 3、切换内置 web 服务器 二、EnableXXX 注解 1、SpringBoot 不能直接获取其他 jar 包/工程中的 Bean 2、原因分析 3、封装 Import 4、Import 注解 5、SpringBoot 自动配…

前端领域的插件式设计

插件&#xff0c;是一个常见的概念。 例如&#xff0c;当我们需要把我们前端代码中的 css 样式提取打包&#xff0c;我们可以用 webpack 的 mini-css-extract-plugin&#xff0c;或者你如果用 rollup 的话&#xff0c;可以选择 rollup-plugin-postcss。 再比如我们可以给 bab…

Python 数组和列表:创建、访问、添加和删除数组元素

Python 没有内置支持数组&#xff0c;但可以使用 Python 列表来代替。 数组 本页将向您展示如何使用列表作为数组&#xff0c;但要在 Python 中使用数组&#xff0c;您需要导入一个库&#xff0c;比如 NumPy 库。数组用于在一个变量中存储多个值&#xff1a; 示例&#xff0…

VSCode 开发 Vue 语法提示

一. 打开应用商店&#xff0c;搜索 vetur &#xff0c;选择第一个&#xff0c;点击安装。 二. 安装完成后&#xff0c;还可以下载 Vue Language Features 解决代码警告的问题。 最后重启 VSCode 就可以使用啦。另外输入 按回车键还可以自动生成 vue 代码格式哦。 原创作者&…

GPT-3 内幕机制可视化解析

GPT-3 内幕机制可视化解析 GPT-3是一个基于Transformer的语言模型,通过不同的层次提取语言不同层面的特性,构建整个语言的语义信息,它学习的过程跟人类正常学习的过程是类似的,开始的时候是一个无监督预训练,如图5-5所示,GPT-3模型可以将网络上的所有文档下载下来,包含 …

AD9371 官方例程HDL详解之JESD204B TX侧时钟生成 (三)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 &#xff1a; AD9371 官方…

Sui提供dApp Kit 助力快速构建React Apps和dApps

近日&#xff0c;Mysten Labs推出了dApp Kit&#xff0c;这是一个全新的解决方案&#xff0c;可用于在Sui上开发React应用程序和去中心化应用程序&#xff08;dApps&#xff09;。mysten/dapp-kit是专门为React定制的全新SDK&#xff0c;旨在简化诸如连接钱包、签署交易和从RPC…

Python生成词云

成品&#xff1a; 代码&#xff1a; import os# 下面的两个包大家注意别导错了 from imageio.v2 import imread from wordcloud import wordcloud# mytext文本是字符串类型的 mytext str() # os.getcwd()是获得当前目录的路径&#xff0c;好像没啥用 读取 with open(os.getcw…

35岁运维工程师到底该何去何从?

你是否经常在网上看到类似的帖子&#xff1a; “运维35岁被裁”、“35岁运维找不到工作”&#xff0c;这样的字眼频频出现在新闻中。如何度过35岁职场危机呢&#xff0c;不妨看看这篇文章&#xff0c;或许对你有启发&#xff01; 一、35岁被称为运维半衰期&#xff0c;究竟为何…