C++STL详解(七)——priority_queue的使用和模拟实现
创始人
2024-06-03 20:22:27
0

文章目录

  • priority_queue的使用
      • priority_queue的介绍
      • priority_queue的定义方式
      • priority_queue各个接口的使用
  • priority_queue的模拟实现
      • 堆的向上调整
      • 堆的向下调整
      • 迭代器区间构造
      • 仿函数
      • priority_queue的模拟实现完整代码

priority_queue的使用

priority_queue的介绍

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

priority_queue的定义方式

方式一
使用的是vector作为底层存储容器,内部为构造为大堆结构。

//大堆
priority_queue, less> q1;

方式二
使用vector作为底层容器,内部构造为小堆结构。

	//小堆
priority_queue, greater> q2;

方式三
不指定底层容器和内部构造的大小堆结构,此时编译器默认使用构造大堆结构。

priority_queue q;

priority_queue各个接口的使用

在这里插入图片描述

例如

int main()
{priority_queue q1;q1.push(3);q1.push(1);q1.push(2);q1.push(4);q1.push(6);q1.push(5);while (!q1.empty()){cout << q1.top() << " ";q1.pop();}q1.push(1);cout << q1.size() << endl;
}

priority_queue的模拟实现

我们知道priority_queue的底层实际上就是堆,所以我们必须先了解一下堆的两种调整。

堆的向上调整

时间复杂度

O(n) = log(n)

基本思路
在大根堆的情况下:
1:传孩子,求父亲。

2: 如果子结点大于父亲结点,就交换子节点与它的父节点的位置,此时子节点就等于原来父亲的结点。

3: 然后又通该子节点向上求得它的父节点,进行循环比较父子结点的大小。

4: 当子节点为0时,就已经与跟结点交换了,循环结束。( 不能使用parent>=0这个条件,当parent = 0,父子结点交换后,此时再计算parent时取整还是等于0,不可能为负数,此时便会无限循环。)

堆的向上调整代码

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;}}
}

堆的向下调整

时间复杂度;
log(n)
基本思路
在大根堆的情况下:
1: 传父亲,求孩子。

2:我们先要求父亲中左右孩子最大的那一个。

注意:使用[]比较时最好先判断一下右孩子必须在的情况。

3: 循环两个步骤: 一直循环的最好情况就是孩子没有超过最后一个数的下标。
如果选出的孩子大于父亲,就交换,并且原来孩子的下标等于父亲的下标。

如果左右孩子都不大于父亲,就说明不用交换,向下调整成功。

      void adjust_down ( size_t parent){//求出左孩子下标size_t child = parent* 2 + 1;while( child < _con.size() ) {//有了右孩子才可以左右孩子比较。if( child + 1 < _con.size() && _con[child]< _con[child+1]){child++;} if( _con[parent] < _con[child] ){swap( _con[parent], _con[child]);parent = child;child = parent* 2 + 1;   }else {break;}}}

迭代器区间构造

时间复杂度:
Nlog(N)
先插入对应的迭代器区间,然后从最后一个数据的父节点开始向下建堆。

template< 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 ) {adjust_down();}
}

仿函数

调用仿函数时,就像调用lsFunc.operator()(1,2)一样。用来比较大小。

         templateclass Less{public:bool operator()( const T& l, const T& r ){return l < r;}};templateclass greater{public:bool operator()( const T& l,const T& r ){return l > r;}};less lsFunc;cout << lsFunc(1, 2) << " ";

priority_queue的模拟实现完整代码

namespace yzh
{ //模板参数代表的类型,根据实参转换为对应的类型。template < class T, Container = vector, class Compare = std:: greater(T) >class priority_queue{public://显示写了,会通过初始化列表在初始化列表内进行初始化,或者调用默认构造。priority_queue(){}  templatepriority_queue(InputIterator first, InputIterator last){while (first != last){_con.push_back(*first);}for( int i = ( _con.size() -1 -1 ) /2;i >= 0; --i  ){adjust_down();}}void push( const T& x ){_con.push_back(x);adjust_up(_con.size() -1 );}//堆的删除是将第一个数据与最后一个元素进行交换,再将最后一个元素删除。//然后再用向下调整的方式调整堆顶。void pop (){std::swap( _con[0], _con[_con.size() - 1 ] );_con.pop_back();adjust_down();}//堆顶只可读不可以修改。const T top() const{assert(!empty() );return_con[0];}size_t size() const{return _con.size();} bool empty() const {return _con.empty();}
private:Container _con;		}
}

相关内容

热门资讯

育碧GDC2018程序化大世界... 1.传统手动绘制森林的问题 采用手动绘制的方法的话,每次迭代地形都要手动再绘制森林。这...
编译原理陈火旺版第三章课后题答... 下面答案仅供参考! 1.编写一个对于 Pascal 源程序的预处理程序。该程序的作用是...
MacBookPro M2芯片... MacBookPro M2芯片下如何搭建React-Native环境目录软件下载环境配置 目录 写在...
Android studio ... 解决 Android studio 出现“The emulator process for AVD ...
pyflink学习笔记(六):... 在pyflink学习笔记(一)中简单介绍了table-sql的窗口函数,下面简单介绍下...
创建deployment 创建deployment服务编排-DeploymentDeployment工作负载均衡器介绍Depl...
gma 1.1.4 (2023... 新增   1、地图工具    a. 增加【GetWorldDEMDataSet】。提供了一套 GEO...
AI专业教您保姆级在暗影精灵8... 目录 一、Stable Diffusion介绍    二、Stable Diffusion环境搭建 ...
vue笔记 第一个Vue应用 Document{{content}}{{...
Unity自带类 --- Ti... 1.在Unity中,自己写的类(脚本)的名字不能与Unit...
托福口语21天——day5 发... 目录 一、连读纠音 二、语料输入+造句输出 三、真题 一、连读纠音 英语中的连读方式有好几种...
五、排序与分页 一、排序 1、语法 ORDER BY 字段 ASC | DESC ASC(ascen...
Linux系统中如何安装软件 文章目录一、rpm包安装方式步骤:二、deb包安装方式步骤:三、tar....
开荒手册4——Related ... 0 写在前面 最早读文献的时候,每每看到related work部分都会选择性的忽略&...
实验01:吃鸡蛋问题 1.实验目的: 通过实验理解算法的概念、算法的表示、算法的时间复杂度和空间复杂度分析&...
8个免费图片/照片压缩工具帮您... 继续查看一些最好的图像压缩工具,以提升用户体验和存储空间以及网站使用支持。 无数图像压...
Spring Cloud Al... 前言 本文小新为大家带来 Sentinel控制台规则配置 相关知识,具体内容包括流控...
多项目同时进行,如何做好进度管... 多项目同时进行,如何做好进度管理? 大多数时候,面对项目进...
ATTCK红队评估实战靶场(二... 前言 第二个靶机来喽,地址:vulunstack 环境配置 大喊一声我...
【MySQL基础】3—多表查询 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTr...