priority_queue模拟

一、什么是priority_queue?

        priority_queue是C++标准库中的一个容器适配器,用于实现优先队列(priority queue)的数据结构。优先队列是一种特殊的队列,其中的元素按照一定的优先级进行排序,每次取出的元素都是优先级最高的。它的优先级是可以通过传入参数自己调整的,它的底层实现通常使用堆(heap)数据结构。以下是堆结构的学习链接:堆(建堆算法,堆排序)-CSDN博客
主要特点
        元素有序:队列中的元素会根据其优先级进行排序,优先级最高的元素总是位于队列的头部(或称为队首)。
        操作:主要操作包括插入新元素(push)、删除优先级最高的元素(pop)以及访问优先级最高的元素(top,但不删除)。
        默认行为:默认情况下,priority_queue使用最大堆实现,即优先级最高的元素(值最大的元素)存储在根节点。但可以通过指定比较函数来改变元素的排序方式,例如使用std::greater可以实现最小堆,即优先级最低的元素(值最小的元素)存储在根节点。

二、priority_queue如何用?

模板参数

priority_queue的模板定义通常包含三个参数:

  • typename T:元素类型。
  • typename Container = std::vector<T>:底层容器类型,默认为std::vector<T>。虽然std::deque也满足条件,但std::vector因其高效的随机访问性能而更常被用作底层容器。
  • typename Compare = std::less<T>:比较函数类型,用于确定元素的优先级。默认为std::less<T>,表示元素按从大到小的顺序排列;若需按从小到大的顺序排列,可指定为std::greater<T>。

以上是priority_queue的接口函数,该篇文章只来学习和模拟c++11以前的接口。

以下是这些接口的使用:

//使用示例
#include<iostream>
#include<queue>
using namespace std;
//这是自定义优先级的一种格式
template<typename T>
class gt
{
public://如果返回true则b优先,返回false则a优先,所以这里使用gt会生成小堆bool operator()(T a, T b){return a > b;}
private:
};
int main()
{priority_queue<int> heap1;//int表示储存的类型priority_queue<int, vector<int>> heap2;//这里vector表示使用的底层容器,这里也可以换成deque<int>。//greater为编译器提供的类模板,默认的优先级是大堆,而使用它可以生成小堆。priority_queue<int, vector<int>, greater<int>> heap3;//当然也可以自己设计一个优先级方式传入,该方法常常用于储存自定义类型,而内置类型编译器提供的就够用。priority_queue<int, vector<int>, gt<int>> heap4;//push接口用于存入元素heap4.push(2);heap4.push(7);heap4.push(1);heap4.push(5);cout << heap4.size() << endl;//size用于计算队列中元素的个数while (!heap4.empty())//empty用于判断队列是否为空{cout << heap4.top() << ' ';//top获取队头元素heap4.pop();//pop删除队头元素}return 0;
}

以上输出为:

三、priority_queue模拟实现

1.模板参数

       首先为了区别于库里面的优先级队列,我们可以用命名空间限制它的作用域。通过观察库里面的priority_queue模板参数一共有三个,第一个为储存的元素类型,第二个参数为需要用的底层容器(默认为vector),第三个参数为用来调整优先级的类模板(需要我们写一个默认模板),那么我们可以做以下设计:

#include<iostream>
#include<vector>
using namespace std;
namespace byte//用命名空间限制它的作用域,来区别于库里面的优先级队列
{template<typename T, class Container = vector<T>, class Compare = less<T>>class priority_queue{public://...private://...};
}

 注意:这里vector模板我们可以使用库里面的,但优先级队列模板(less<T>)需要我们自己写。

2.成员变量

        STL的任何模拟,如果在考虑成员变量如何设计而发愁,我们可以去想如何储存对象的数据进而来设计我们的成员变量。这里我们用的是容器Container(即vector<int>)来储存数据的,所以我们的成员变量之一类型一定是Container,其次因为想到不同对象传入的Compare可能不同,具有特殊性,所以我们也可以把Compare(优先级调整的类模板)作为成员变量。如下:

private:Container arr;Compare comp;

3.成员函数

        因为在priority_queue模拟中并不涉及到动态内存开辟和一些特殊理,所以这里的构造函数用编译器默认提供的构造函数就够用了,并不需要我们自己编写。

        在优先级队列中因为涉及到堆的调整所以在push和pop接口的设计中有些复杂,其他接口的设计都非常简单就不在讲解,后面大家直接看源码。

3.1.push

        首先需要把arr看做是一个堆结构,无论arr里面有没有元素,然后直接把元素push_back到arr中,此时该元素所在位置为堆底,而且并不一定是正确的位置,接下来要做的就是对该元素进行向上调整。

父子节点的定义:子节点记为child,父节点记为father。

child=arr.size()-1

father=(child-1)/2(理解原理后可以当做公式记忆,可通过一下链接参考学习)

向下调整的方法我在以下文章中有具体讲解:

堆(建堆算法,堆排序)_初始建堆算法-CSDN博客

		void AdjustUP(){int child = arr.size() - 1, father = (child - 1) / 2;while (child > 0){if (comp(arr[father], arr[child])){std::swap(arr[child], arr[father]);child = father;father = (child - 1) / 2;}else{break;}}}

3.2.pop

        该函数主要功能是pop堆顶元素,但是如果直接pop堆顶元素(下标为0)的话,那么下标为1的会成为堆顶元素,会使原来的父子关系和兄弟关系混乱,要重新调整起来极其复杂,所一需要换一种方案,我们可以把堆顶元素与堆底元素交换然后pop堆底元素,然后对堆进行向下调整。

父子节点的定义:子节点记为child,父节点记为father。

father=0

child=father*2+1(这里father和child的计算公式是可以互推的)

向下调整的方法我在以下文章中有具体讲解:

堆(建堆算法,堆排序)_初始建堆算法-CSDN博客

四、源码

#include<iostream>
#include<vector>
using namespace std;
namespace byte
{template<typename T>class less{public://如果返回true则b优先,返回false则a优先,所以这里使用gt会生成小堆bool operator()(T a, T b){return a < b;}private:};template<typename T>class greater{public://如果返回true则b优先,返回false则a优先,所以这里使用gt会生成小堆bool operator()(T a, T b){return a > b;}private:};template<typename T, class Container = vector<T>, class Compare = less<T>>class priority_queue{public:void AdjustUP(){int child = arr.size() - 1, father = (child - 1) / 2;while (child > 0){if (comp(arr[father], arr[child])){std::swap(arr[child], arr[father]);child = father;father = (child - 1) / 2;}else{break;}}}void AdjustDOWN(){int father = 0, child = father * 2 + 1;while (child < arr.size()){if (child + 1 < arr.size() && comp(arr[child], arr[child + 1])){child++;}if (comp(arr[father], arr[child])){std::swap(arr[child], arr[father]);father = child;child = father * 2 + 1;}else{break;}}}void push(T x){arr.push_back(x);AdjustUP();}void pop(){std::swap(arr[0], arr[arr.size() - 1]);arr.pop_back();AdjustDOWN();}T top(){return arr[0];}size_t size(){return arr.size();}bool empty(){return arr.size() == 0;}private:Container arr;Compare comp;};
}

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

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

相关文章

从零开始掌握Vue实例

从零开始掌握Vue实例&#xff1a;深入理解数据绑定与生命周期的核心秘诀 引言 简要介绍主题&#xff1a; 在学习Vue.js的过程中&#xff0c;Vue实例是最基础也是最关键的部分。Vue实例是Vue应用的核心&#xff0c;它是数据、DOM元素和Vue组件之间的桥梁。掌握Vue实例的使用对于…

文件上传面板中限制需要的文件格式,并且隐藏“所有文件”选项

直接说需求&#xff1a;需要实现在文件上传面板中限制需要的文件格式&#xff0c;并且不想展示“所有文件”这个选项&#xff0c;应该怎么做嘞&#xff1f;效果如下图&#xff1a; 这里用到了 window.showOpenFilePicker 方法实现&#xff0c;首先定义接受的格式及限制&#xf…

格行“信号增强技术”引领行业创新,格行随身WiFi带你感受不一样的速度与激情,行业第一的随身WiFi并非浪得虚名!

近年来&#xff0c;随着市场保有量的不断提升与相关技术的不断扩展&#xff0c;我国随身WiFi市场已经到了发展质量更高的“2.0”阶段&#xff0c;消费者对随身WiFi的需求变得多元且“高级”。与之对应的供给端&#xff0c;品牌之间的竞争也从未停止&#xff0c;有的品牌选择卷价…

如何使用ssm实现实验室仪器设备管理系统

TOC ssm354实验室仪器设备管理系统jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化…

快来尝尝,食家巷荞面甜甜圈超赞

当荞面与甜甜圈相遇&#xff0c;便诞生了食家巷荞面甜甜圈&#xff0c;一种独具特色的美食体验。 食家巷荞面甜甜圈&#xff0c;外形圆润可爱&#xff0c;色泽金黄诱人。那精致的环状造型&#xff0c;仿佛是一个小小的魔法圈&#xff0c;散发着迷人的魅力。 与传统甜甜圈…

计算机网络面试真题总结(七)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 什么是对称加密、非对称加密&#xff1f; 对称加密是一种常用的加…

探索AI智能问答:改变未来交流的新动力

人工智能(AI)是当今科技领域中最具潜力和影响力的技术之一&#xff0c;AI智能问答系统更是这一领域中的一颗璀璨明珠。随着大数据和机器学习的发展&#xff0c;AI智能问答系统已经不仅仅是科幻小说中的幻想&#xff0c;而是正逐步融入我们的日常生活&#xff0c;从客户服务到教…

生成式AI扩散模型-Diffusion Model【李宏毅2023】概念讲解、原理剖析笔记

目录 一、Diffusion的基本概念和运作方法 1.Diffusion Model是如何运作的&#xff1f; 2.Denoise模块内部正在做的事情 如何训练Noise predictor&#xff1f; 1&#xff09;Forward Process (Diffusion Process) 2&#xff09;noise predictor 3.Text-to-Image 4.两个A…

入门Java第一步—>IDEA的下载与安装与JDK的环境配置(day01)

1.JDK的下载与安装 jdk的安装链接分为不同操作系统如下,点击链接跳转下载页面&#xff1a; windows操作系统JDK下载链接(按住键盘ctrl键单击链接即可)&#xff1a; 链接7天有效&#xff0c;有需要的评论区找我哈 通过网盘分享的文件&#xff1a;jdk-8u271-windows-x64.exe 链…

人工智能如何将人机交互提升到新水平

随着人工智能模型在语音识别和合成、文本处理和多模态性方面的卓越表现&#xff0c;终极语音用户界面可能很快就会无处不在。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 那是一个典型的星期五下午&#xff0c;我们刚刚结束了一个…

如何用wireshark分析找出url接口和param参数???

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

Linux 内核源码分析---IPv6 数据包

IPv6是英文“Internet Protocol Version 6”&#xff08;互联网协议第6版&#xff09;的缩写&#xff0c;是互联网工程任务组&#xff08;IETF&#xff09;设计的用于替代IPv4的下一代IP协议&#xff0c;其地址数量号称可以为全世界的每一粒沙子编上一个地址。 由于IPv4最大的…

Tapd敏捷开发平台的使用心得

Tapd敏捷开发平台的使用心得 一、Tapd 简介 TAPD(Tencent Agile Product Development),腾讯敏捷产品研发平台行业领先的敏捷协作方案,贯穿敏捷产品研发生命周期的一站式服务,了解敏捷如下图 二、几个核心模块概念 需求迭代缺陷故事墙前期项目需求的管理,可以按类别建…

22AP10 SS524 平替 海思HI3521DV200 可提供开发资料

22AP10 是针对多路高清/超高清&#xff08;1080p/4M/5M/4K&#xff09;DVR 产品应用开发的新一代专 业 SoC 芯片。22AP10 集成了 ARM Cortex-A7 四核处理器和性能强大的图像分析工具 推理引擎&#xff0c;支持多种智能算法应用。同时&#xff0c;22AP10 还集成了多路 MIPI …

【可兼容的】protobuf、streamlit、transformers、icetk、cpm_kernels版本号

搞大模型训练的工作不可避免地需要很多库&#xff0c;但是非常讨厌的事情是这些库动不动就不兼容。最近在做文本分类训练的时候又遇到了这个问题&#xff0c;为了避免后面再安装包的时候把我之前的环境破坏了&#xff0c;所以特地来记录一下&#xff1a;protobuf、streamlit、t…

排序算法见解(2)

1.快速排序 1.1基本思想&#xff1a; 快速排序是通过一趟排序将待排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另一部分的所有数据都要小&#xff0c;然后再按此方法对这两部分数据分别进行快速排序&#xff0c;整个排序过程可以递归进行&#xff0c;以…

解决Springboot项目Maven下载依赖速度慢的问题

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

智能客服系统:提升客户体验与企业效率的革命性工具

在当今数字化时代&#xff0c;企业与客户之间的互动方式正在迅速改变。智能客服系统作为一种新兴技术&#xff0c;不仅在提高客户满意度方面发挥着重要作用&#xff0c;还能够大大提高企业的运营效率。本文将详细探讨智能客服系统的工作原理、优势、实施步骤以及未来发展趋势。…

AI的未来已来:GPT-4商业应用带来的无限可能

随着人工智能技术的快速发展&#xff0c;OpenAI于2023年3月15日发布了多模态预训练大模型GPT-4&#xff0c;这一里程碑式的进步不仅提升了AI的语言处理能力&#xff0c;还拓展了其应用范围。本文将深入探讨GPT-4的技术进步、商业化进程、用户体验改善、伦理和社会影响&#xff…

vue项目安装pnpm和无法加载pnpm,已解决

vue3安装pnpm命令&#xff1a; 1.提升依赖安装速度&#xff1a;npm config set registry https://registry.npmjs.org 2.安装pnpm:npm install -g pnpm 3.安装pnpm依赖&#xff1a;pnpm install 4…windows电脑&#xff0c;无法安装pnpm&#xff0c;pnpm install命令&#xff0…