STL库 —— priority_queue 的编写

目录

一、 优先级队列的介绍

二、优先级队列的使用

2.1 建大堆 less

2.2 建小堆 greater

2.3 详解 greater 与 less

三、 priority_queue 的模拟实现 

3.1 编写框架 

3.2 编写简单函数

3.2 进堆 向上调整

3.3 出堆 向下调整

四、完整代码 


一、 优先级队列的介绍

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的
2. 其内容类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
empty():检测容器是否为空
size():返回容器中有效元素个数
front():返回容器中第一个元素的引用
push_back():在容器尾部插入元素

5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数 make_heap、push_heap 和 pop_heap 来自动完成此操作。

二、优先级队列的使用

优先级队列的传入参数有三个,分别是对象类型 T ,默认构造容器 Container , 比较方式  Compare ,从下图可以看出,后两个参数都有缺省值,当要改变堆中的比较方式时,要记得传入第二个模板参数!

2.1 建大堆 less

首先,优先级队列的首元素默认是最大的,如下图是默认情况下的对顶元素是堆中的最大值,库中默认缺省值为 less 。

2.2 建小堆 greater

但是,类似于 qsort 函数,可以提供特定的方式以达到特定的需求,如下,库中提供的 greater 可以使堆顶元素变为最小值:

除了上面实例化对象时的构造方式,可以在实例化对象时就传入参数:

vector<int> v = { 2, 9, 1, 6, 7, 4, 0 };	
priority_queue<int, vector<int>, greater<int>> pq2(v.begin(), v.end());

2.3 详解 greater 与 less

在C++中,std::greaterstd::less 实际上是函数对象(也称为仿函数或者functors),而非简单的函数。一个函数对象是任何提供了函数调用运算符(operator())的对象。
这意味着,对象行为类似于函数:可以通过提供参数列表并使用圆括号语法来"调用"它。

 下面直接来看一下 greater 与 less 的底层实现:

    template<class T>struct greater{bool operator()(T& left, T& right){return left > right;}};template<class T>struct less{bool operator()(T& left, T& right){return left < right;}};

这样对于实例化对象时传入的 greater 或 less 就有了比较清晰的认识,而这也是不需要传入参数的原因,它们压根就不是个函数,而只是个对 () 的操作符重载。

这里先提一下下面的向上调整:


可以看到这里类似使用函数调用,但其实是创建了匿名类。

三、 priority_queue 的模拟实现 

3.1 编写框架 

如下,首先搭建一个框架:

    template<class T>struct greater{bool operator()(T& left, T& right){return left > right;}};template<class T>struct less{bool operator()(T& left, T& right){return left < right;}};template <class T, class Container = std::vector<T>, class Compare = less<T> >class my_priority_queue{public:my_priority_queue(){_con();}void push(T x){}void pop(){}size_t size(){}bool empty(){}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top() const{}private:Container _con;};

3.2 编写简单函数

从对 priority_queue 的介绍得知,有几个函数都是很好写的:

        size_t size(){return _con.size();}bool empty(){return _con.empty();}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top() const{return _con.front();}

3.2 进堆 向上调整

但是, push 和 pop 会更复杂一些,这涉及到对堆内容的调整,调整的方法和 C语言 中堆的向上与向下调整算法大致相同,下面以 less 建大堆举例:

		void AdjustUp(int child){int father = (child - 1) / 2;while (child > 0){if (Compare()(_con[father], _con[child])){swap(_con[child], _con[father]);child = father;father = (child - 1) / 2;}elsereturn;}}void push(T x){_con.push_back(x);AdjustUp(_con.size() - 1);}

暂时先组略的用调试的方法对照的看一下:

3.3 出堆 向下调整

		void AdjustDown(){int father = 0;int child = father * 2 + 1;while(child < _con.size()){	if (child + 1 < _con.size() && Compare()(_con[child], _con[child + 1])) child += 1;if (_con[father] < _con[child]){swap(_con[father], _con[child]);father = child;child = father * 2 + 1;}elsereturn;}}void pop(){if (_con.empty()) return;swap(_con.front(), _con.back());_con.pop_back();AdjustDown();}

四、完整代码 

#include <iostream>
#include<vector>
using namespace std;
namespace Flash
{template<class T>struct greater{bool operator()(T& left, T& right){return left > right;}};template<class T>struct less{bool operator()(T& left, T& right){return left < right;}};template <class T, class Container = std::vector<T>, class Compare = less<T> >class my_priority_queue{public:my_priority_queue() : _con(){}void push(T x){_con.push_back(x);AdjustUp(_con.size() - 1);}void pop(){if (_con.empty()) return;swap(_con.front(), _con.back());_con.pop_back();AdjustDown();}size_t size(){return _con.size();}bool empty(){return _con.empty();}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top() const{return _con.front();}private:void AdjustUp(int child){int father = (child - 1) / 2;while (child > 0){if (Compare()(_con[father], _con[child])){swap(_con[child], _con[father]);child = father;father = (child - 1) / 2;}elsereturn;}}void AdjustDown(){int father = 0;int child = father * 2 + 1;while(child < _con.size()){	if (child + 1 < _con.size() && Compare()(_con[child], _con[child + 1])) child += 1;if (_con[father] < _con[child]){swap(_con[father], _con[child]);father = child;child = father * 2 + 1;}elsereturn;}}private:Container _con;};void test_push(){my_priority_queue<int> mpq;mpq.push(3);mpq.push(2);mpq.push(5);mpq.push(1);mpq.push(4);}void test_pop(){my_priority_queue<int> mpq;mpq.push(3);mpq.push(2);mpq.push(5);mpq.push(1);mpq.push(4);while (!mpq.empty()){cout << mpq.top() << endl;mpq.pop();}}
}

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

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

相关文章

web轮播图

思路&#xff1a; 例如&#xff1a;有5张轮播的图片&#xff0c;每张图片的宽度为1024px、高度为512px.那么轮播的窗口大小就应该为一张图片的尺寸&#xff0c;即为&#xff1a;1024512。之后将这5张图片0px水平相接组成一张宽度为&#xff1a;5120px,高度依然为&#xff1a;5…

守望先锋2怎么在steam上玩 守望先锋归来steam下载安装

守望先锋2怎么在steam上玩 守望先锋归来steam下载安装 《守望先锋2》是知名游戏开发商暴雪娱乐开发的团队射击游戏。与第一部相比&#xff0c;守望先锋2加入了更多元素和新特性。游戏设定在未来的世界&#xff0c;玩家可以选择不同的英雄&#xff08;heroes&#xff09;加入战…

python聊天室

python聊天室 文章目录 python聊天室chat_serverchat_client使用方式1.局域网聊天2.公网聊天 下面是一个简单的示例&#xff0c;包含了chat_client.py和chat_server.py的代码。 chat_server chat_server.py监听指定的端口&#xff0c;并接收来自客户端的消息&#xff0c;并将消…

35岁+技术人的困境与选择

前言 最近一些大厂的持续裁员事件&#xff0c;让职场年龄焦虑的话题又火热起来了。职场的年龄焦虑是客观存在的事实&#xff0c;这是市场与资本相互作用的必然结果。资本在运作的过程中&#xff0c;肯定是要逐利的&#xff0c;最终也是要趋向于利润最大化的。 因此&#xff0…

WdatePicker异常,无法弹出日期选择框

官网&#xff1a;My97日期控件官方网站 My97 DatePickerhttp://www.my97.net/ 可能使版本太老了&#xff0c;可以更新一下&#xff0c;然后根据官方的文件进行使用。 我的异常是因为在网上找的包里面缺少文件&#xff0c;去官网拉了一下最新的就行了。

AR地图导览小程序是怎么开发出来的?

在移动互联网时代&#xff0c;AR技术的发展为地图导览提供了全新的可能性。AR地图导览小程序结合了虚拟现实技术和地图导航功能&#xff0c;为用户提供了更加沉浸式、直观的导览体验。本文将从专业性和思考深度两个方面&#xff0c;探讨AR地图导览小程序的开发方案。 编辑搜图 …

数据结构之排序了如指掌(二)

目录 题外话 正题 选择排序 选择排序思路 选择排序代码详解 选择排序复杂度 双向选择排序 双向选择排序思路 双向选择排序代码详解 堆排序 堆排序思路 堆排序代码详解 堆排序复杂度 冒泡排序 冒泡排序思路 冒泡排序代码详解 冒泡排序复杂度 小结 题外话 今天…

变配电场所智能综合监控系统无人化与自动化升级改造

一 项目背景 国家电力建设飞速发展,为了提高管理水平,智能化建设迫在眉睫。变配电场所作为电网中的核心单元,数量巨大,是智能化建设的中坚部分。但由于变配电场所分布的地理位置过于分散&#xff0c;且配电网的自动化水平有待提高,单纯依靠人力来对变配电场所进行巡视,不仅增加…

python 文件输入输出

python 文件输入输出 一、输入输出1. 输出格式美化2. 旧式字符串格式化3. 读取键盘输入4. 读和写文件5. 文件对象的方法6. pickle 模块 二、文件操作1. File(文件) 方法2. mode 参数有&#xff1a;3. file 对象 三、 OS 文件操作1. OS 文件/目录方法 四、代码概览&#xff08;输…

【canvas】canvas综合运用:心形图案

#简言 利用canvas画出心形图案。 心形 心形图案可以两个椭圆相交组合&#xff0c;也可以直接画路径实现。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" conte…

深入了解CSS 元素尺寸单位:像素、百分比、em、rem 和 viewport 单位

你好&#xff0c;我是小白Coding日志&#xff0c;一个热爱技术的程序员。在这里&#xff0c;我分享自己在编程和技术世界中的学习心得和体会。希望我的文章能够给你带来一些灵感和帮助。欢迎来到我的博客&#xff0c;一起在技术的世界里探索前行吧&#xff01; 在前端开发中&am…

labelimg安装和使用(解决闪退问题)

&#x1f308;个人主页&#xff1a;Rookie Maker &#x1f525; 系列专栏&#xff1a;计算机视觉 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于IT的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到我的代码世界~ &#x1f601; 喜…

图与图搜索算法

图搜索算法是一个非常重要的概念&#xff0c;它是计算机科学中图论和算法设计的基础部分。在开始讨论图搜索算法之前&#xff0c;我们需要先理解什么是图以及图的基本结构。 什么是图&#xff1f; 图&#xff08;Graph&#xff09;是一种非线性数据结构&#xff0c;它由一组点…

C 错误处理

C 语言不提供对错误处理的直接支持&#xff0c;但是作为一种系统编程语言&#xff0c;它以返回值的形式允许您访问底层数据。在发生错误时&#xff0c;大多数的 C 或 UNIX 函数调用返回 1 或 NULL&#xff0c;同时会设置一个错误代码 errno&#xff0c;该错误代码是全局变量&am…

Redis集群和哨兵

Redis集群和哨兵是Redis系统中的重要组件&#xff0c;它们在保障数据可靠性、扩展性和高可用性方面发挥着关键作用。 Redis集群主要解决了单一Redis实例在存储和性能上的限制。通过将数据分散到多个Redis节点上&#xff0c;集群能够实现数据的水平扩展&#xff0c;从而支持更大…

点云的投影------PCL

点云的投影 /// <summary> /// 参数化模型投影点云 /// </summary> /// <param name"cloud">点云</param> /// <param name"x">投影平面x面的系数</param> /// <param name"y"></param> /// &…

Python下利用Selenium获取动态页面数据

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Java中方法的重载:初学者易懂的指南

Java中方法的重载&#xff1a;初学者易懂的指南 在Java编程中&#xff0c;方法的重载&#xff08;Overloading&#xff09;是一个非常重要的概念。它允许我们在同一个类中定义多个同名但参数列表不同的方法。这样&#xff0c;我们就可以根据传递的参数类型和数量来执行不同的操…

使用python进行网站答题操作

介绍&#xff1a; 使用Python和DrissionPage模块编写自动化脚本&#xff0c;以模拟人的行为访问网站并获取题目答案进行自动答题。这个脚本似乎是为答题网站设计的&#xff0c;通过监控特定数据包地址来获取题目答案&#xff0c;并模拟点击正确答案进行答题。 代码中的逻辑包…

C++奇迹之旅:探索C++拷贝构造函数

文章目录 &#x1f4dd;拷贝构造函数&#x1f320; 概念&#x1f309;特征 &#x1f320;浅拷贝(值拷贝)&#x1f309;深拷贝 &#x1f320;拷贝构造函数典型调用场景&#x1f320;应用时效率的思考&#x1f6a9;总结 &#x1f4dd;拷贝构造函数 &#x1f320; 概念 在现实生…