C++——优先级队列priority

news/2024/11/17 4:56:54/

一、介绍

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

二、基本接口

函数声明接口说明
priority queue()构造一个空的优先级队列
priority queue(first,last)

用迭代器构造

empty()判空
top()返回堆顶元素
push(x)插入元素x
pop()删除堆顶元素

三、模拟实现

1.成员变量

成员变量采用适配器模式,默认给的是vector

template<class T,class Con = vector<T>,class Comapre = less<T>>
class heap
{private:Con _con;...
}

2.向上调整adjust_up 与向下调整adjust_down

优先级队列最核心的两个实现就是向上调整和向下调整,是实现堆算法的核心

adjust_up

void adjust_up(size_t child)
{size_t parent = (child - 1) / 2;while (child > 0){if (com(_con[parent] , _con[child]))//com是伪函数对象,默认是小于{swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

adjust_down

向下调整的实现需要考虑只有左孩子没有右孩子两个孩子都有这两种情况,画图判断边界条件

		//com是仿函数,默认为小于void adjust_down(size_t parent){size_t lchild = parent * 2 + 1;size_t rchild = lchild + 1;while (lchild < _con.size())//没有孩子就结束向下调整{if (lchild + 1 == _con.size())//有一个左孩子{if (com(_con[parent] , _con[lchild])){swap(_con[parent], _con[lchild]);parent = lchild;}else{break;}}else//存在右孩子{size_t child = com(_con[rchild] , _con[lchild]) ? lchild : rchild;if (com(_con[parent] , _con[lchild])){swap(_con[parent], _con[child]);}else{break;}parent = child;//更新}//更新孩子lchild = parent * 2 + 1;rchild = lchild + 1;}}

3.构造函数

构造函数又两个接口,一个是构造一个空的优先级队列,一个是用迭代器进行构造

用迭代器构造的实现中,涉及建堆算法,即从最后一个节点的父节点开始向下调整,一直调整到根,就可以实现建堆,时间复杂度为O(n)

		heap():_con(){}template<class Iterator>heap(Iterator first, Iterator last):_con(first,last){//建堆算法for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i){adjust_down(i);}}

4.push 和 pop

push:将数据尾插后,不断向上调整,使其重新成为一个堆

pop:将堆顶的元素与堆尾的最后一个元素交换,然后尾删,对堆顶刚交换的元素进行向下调整

		void push(const T& x){_con.push_back(x);adjust_up(_con.size()-1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}

5.基本参数

注意!在返回top时,只需要返回const修饰的堆顶,堆顶一般不允许进行修改,不然会破坏堆

		size_t size(){return _con.size();}bool empty(){return _con.empty();}const T& top()const{return _con.front();}

四、本章重点(新知识)—— 仿函数

伪函数的本质是类,在本章的模拟实现中,用仿函数去操控堆是大堆还是小堆,实际上就是用类去重载了(),实现类型于比较函数的功能,用实例化的对象去调用这个重载,这样做的好处是在传参的时候,可以通过模板参数去传,相比于回调函数用处更大更方便,并且开放性很强,可以自己实现一个仿函数去传,也可以使用库里的,本次模拟实现中,只是使用仿函数的其中一个情景

template<class T>
struct greater
{bool operator()(const T& x,const T& y){return x > y;}
}
template<class T>
struct less
{bool operator()(const T& x,const T& y){return x < y;}
}//类模板 : template<class T , class Con = vector<T> , class Comapre = less<T>>

五、相关的经典OJ题

1.topK问题

题目链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述

找到一组数据中,前k个或者第k个(排序后)的数据

解题思路

直接用堆去解决,在本题目中,最好的方法是利用快排的思想,才能实现O(n)的时间复杂度

参考代码

class Solution 
{
public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int> hp(nums.begin(),nums.end());while(--k){hp.pop();}return hp.top();}
};

总结:

本章整理了关于优先级队列的相关知识,其中比较重要的一个概念是仿函数的概念,属于现阶段的新知识点,这里简单的提一下,今后会学习更多相关的知识


http://www.ppmy.cn/news/1173275.html

相关文章

如何部署和配置IPv6

环境&#xff1a; IPv6 问题描述&#xff1a; 如何部署和配置IPv6 解决方案&#xff1a; 要了解 IPv6&#xff0c;首先需要了解 IPv4&#xff0c;因为 IPv6 是 IPv4 的升级版本。IPv4 是互联网上最常见的 IP 地址协议&#xff0c;它使用 32 位地址&#xff0c;可以表示大约…

使用VisualSVN在Windows系统上设置SVN服务器,并结合内网穿透实现公网访问

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

1024啊啊啊啊啊啊

1024 程序员节快乐&#xff0c;没什么想发的&#xff0c;只是想要个1024胸章。

D - United We Stand

思路&#xff1a; &#xff08;1&#xff09;题目要求将集合A划分为B&#xff0c;C两组&#xff0c;使得C中任意数都不是B中的除数 &#xff08;2&#xff09;直观感受&#xff0c;只要让C中数比B中大&#xff0c;则满足条件&#xff0c;不妨只取最大的放入C中&#xff1b; …

vue:项目开发:在请求拦截器中处理loading加载 请求头(headers)的检验配置 接口文档出现的特殊符号处理的方式

请求拦截器中的一些处理逻辑 // 自定义配置实例 (自己配置的请求) import store from /store import axios from axios import { Toast } from vantconst instance axios.create({baseURL: http://cba.itlike.com/public/index.php?s/api/,timeout: 5000 })// 添加请求拦截器…

thinkphp 解决跨域的三个方式

1. 在tp入口index.php 加上header //支持跨域 header("Access-Control-Allow-Origin:*"); header(Access-Control-Allow-Methods:*); header(Access-Control-Allow-Headers:x-requested-with, content-type,token); 2. 在route.php加上 allowCrossDomain()&#xff…

使用imx 8m 测试matter协议功能

yocto这玩意太耗硬盘和cpu了&#xff0c;网上租个E5神机来编吧 参考网址&#xff1a; https://github.com/nxp-imx/meta-matter 请使用Ubuntu-20.04。18.04python版本太老 注意repo会出现此报错&#xff0c;可以无视&#xff1a; repo sync 同步不了代码 error: RPC failed;…