当前位置: 首页 > news >正文

暴力数据结构之优先级队列的解析及其模拟实现(C++)

1.认识优先级队列

如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。

优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素 (3)删除

一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行

在默认情况下优先级最高的通常是队列中最大的数字,当然我们也可以只用仿函数来更改其队列中元素的优先级,优先级队列的底层实质上就是堆,也就是数组

2.模拟实现优先级队列

首先回顾一下完全二叉树中父节点与左右子结点的关系:left child = parent * 2 + 1; right child = parent * 2 + 2; parent = (child - 1) / 2

namespace bit
{template<class T,class Container = vector<T>>class priority_queue{public://向上调整void AdjustUp(size_t child){size_t parent = (child - 1) / 2;while (child > 0){//将大的值移向堆顶,建大堆if (_con[parent] < _con[child]){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}//向下调整void AdjustDown(size_t parent){//假设为左子结点size_t child = parent * 2 + 1;while (child > 0){//找到大的子结点 if (child + 1 < _con.size() && _con[child] < _con[child + 1]){child++;}if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void push(const T& x){_con.push_back(x);//从堆底向上调整AdjustUp(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();//从堆顶向下调整AdjustDown(0);}const T& top(){return _con[0];}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
}

3.仿函数 

首先我们要知道仿函数的本质是一个类,为了使代码更加具有灵活性,我们就使用到了仿函数来重载 operator(),以达到改变大/小堆的功能

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 bit
{//默认是大堆template<class T,class Container = vector<T>,class Compare = Less<T>>class priority_queue{public://向上调整void AdjustUp(size_t child){Compare com;size_t parent = (child - 1) / 2;while (child > 0){//将大的值移向堆顶,建大堆//if (_con[child] < _con[parent])if (com(_con[child],_con[parent])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}//向下调整void AdjustDown(size_t parent){Compare com;//假设为左子结点size_t child = parent * 2 + 1;while (child > 0){//找到大的子结点 //if (child + 1 < _con.size() && _con[child] < _con[child + 1])if (child + 1 < _con.size() && com(_con[child],_con[child + 1])){child++;}//if (_con[parent]<_con[child])if (com(_con[parent],_con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void push(const T& x){_con.push_back(x);//从堆底向上调整AdjustUp(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();//从堆顶向下调整AdjustDown(0);}const T& top(){return _con[0];}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
}

4.实战代码练习 

LCR076.数组中的第K个最大元素,本题使用优先级队列可以很简单的解决问题

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {//将元素存储到优先级队列priority_queue<int> pq;for(auto& e : nums){pq.push(e);}//取出前k-1个最大元素,剩下的元素中最大的元素就是第k个最大元素for(int i = 0;i < k - 1;i++){pq.pop();}return pq.top();}
};

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python读取excel
  • Flask如何处理POST请求
  • 两个月冲刺软考——逻辑地址与物理地址的转换(例题+讲解);文件类型的考点
  • 【C++】手动实现nique_ptr智能指针
  • 解决AbortController中断请求无法再次请求
  • 招聘网站项目
  • Docker in Docker 实践 on mac
  • 跨越技术壁垒:EasyCVR为何选择支持FMP4格式,重塑视频汇聚平台标准
  • Jenkins+docker+springboot 一键自动部署项目步骤
  • docker-mysql容器数据卷挂载
  • 大端模式和小端模式
  • 对话万兴科技副总裁朱伟:2024年将迎来AI视频年
  • centos安装docker并配置加速器
  • LeetCode376 摆动序列
  • 《酒饮真经》第二部——劝酒十五式
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Gradle 5.0 正式版发布
  • js中的正则表达式入门
  • KMP算法及优化
  • Laravel 菜鸟晋级之路
  • linux学习笔记
  • log4j2输出到kafka
  • magento2项目上线注意事项
  • MaxCompute访问TableStore(OTS) 数据
  • MySQL的数据类型
  • Netty 4.1 源代码学习:线程模型
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • session共享问题解决方案
  • supervisor 永不挂掉的进程 安装以及使用
  • Xmanager 远程桌面 CentOS 7
  • 订阅Forge Viewer所有的事件
  • 将回调地狱按在地上摩擦的Promise
  • 前端攻城师
  • 如何设计一个比特币钱包服务
  • 为什么要用IPython/Jupyter?
  • 用简单代码看卷积组块发展
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 7行Python代码的人脸识别
  • hi-nginx-1.3.4编译安装
  • linux 淘宝开源监控工具tsar
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #14vue3生成表单并跳转到外部地址的方式
  • #考研#计算机文化知识1(局域网及网络互联)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (27)4.8 习题课
  • (TOJ2804)Even? Odd?
  • (不用互三)AI绘画工具应该如何选择
  • (一)80c52学习之旅-起始篇
  • (一)Java算法:二分查找
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl