《算法笔记》6.6 priority_queue详解

6.6 priority_queue详解

priority_queue又称为优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
当然,可以在任何时候往优先队列里面加入(push)元素,而优先队列底层的数据结构会随时调整结构,使得每次的队首元素都是优先级最大的
要使用queue,需先添加头文件和命名空间。

#include<queue>
using namespace std ;

1. priority_queue的定义

priority_queue< typename > q ;

2. priority_queue容器内元素的访问

和队列不一样的是,优先队列没有front()函数和back()函数,而只能通过top()函数来访问队首元素(也可称为堆顶元素),也就是优先级最高的元素。

3. priority_queue常用函数解析

(1)push()

push(x)令x入队,复杂度为O(logN)。

(2)top()

top()函数可以获得队首元素,时间复杂度为O(1)。

(3)pop()

pop()令队首元素出队,时间复杂度为O(logN)。

(4)empty()

empty()检测优先队列是否为空,时间复杂度为O(1)。

(5)size()

返回优先队列内元素个数,复杂度为O(1)。

4. priority_queue内元素优先级的设置

下面分别介绍基本数据类型(例如int , double ,char)与结构体类型的优先级设置。

(1)基本数据类型的优先级设置

优先队列对他们的优先级设置一般是数字大的优先级高。对基本数据类型来说,下面两种优先队列的定义是等价的(以int为例)

priority_queue<int> q ;
//等价于
priority_queue<int , vector<int> , less<int> > q ;

第二种方式多了两个参数:一个是vector,用来承载底层数据结构堆(heap)的容器,如果第一个参数是char,则此处只需填写vector。另一个是less,是对第一个参数的比较类,less<int>表示数字大的优先级越大,而greater<int>表示数字小的优先级大。
因此,如果想让优先队列总是把最小的元素放在队首,只需进行如下定义:

 priority_queue<int , vector<int> , greater<int> > q ;

(2)结构体的优先级设置

举一个水果的例子,可以对水果的名称和价格建立一个结构体:

struct fruit{
    string name ;
    int price ;
};

现在希望按水果的价格高的为优先级高,就需要重载(overload)小于号 “<”。重载是指对已有的运算符进行重新定义,也就是说,可以改变小于号的功能。

struct fruit{
    string name ;
    int price ;
    friend bool operator < ( fruit f1 , fruit f2 ){
        return f1.price < f2.price ;
    }
};

重载大于号会编译错误,因为从数学上来说只需要重载小于号,即f1>f2等价于判断f2<f1,而f1==f2则等价于!(f1<f2)&&!(f2 < f1)

那么,有没有办法跟sort中的cmp函数那样写在结构体外面呢?自然是有的。

struct cmp{
    bool operator () ( fruit f1 , fruit f2 ){
     	return f1.price > f2.price ;
    }

};

在这种情况下,需要使用之前的定义方式

priority_queue< fruit , vector<fruit> , cmp > q ;

5. priotrity_queue的常见用途

priority_queue可以解决一些贪心问题,也可以对Dijkstra算法进行优化。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值