【算法笔记】优先队列priority_queue

本文详细介绍了C++中的优先队列priority_queue,包括其底层堆实现、元素优先级设置方法以及常用函数。优先队列可以通过自定义比较类或重载运算符来设置不同类型的元素优先级。同时,文章提到了优先队列在解决贪心问题和优化Dijkstra算法等场景中的应用。
摘要由CSDN通过智能技术生成

优先队列priority_queue

底层是用实现的,

队首元素总是优先级最大的。

 头文件+命名空间:

#include <queue>

using namespace std;

定义:

priority_queue<typename> name; 

一、元素优先级的设置

1.基本数据类型优先级设置

默认是int,double型等数字大的优先级高,char型等按字典序

priority_queue<int> q;
priority_queue<int, vector<int>,less<int> > q; //特别注意最后两个>之间有空格

 第二种定义方式:

第二个参数:用来承载底层数据结构堆(heap)的容器

第三个参数:对第一个参数的比较类

less<int>     :数字大的优先级大

greater<int>:数字小的优先级大

//最大堆
priority_queue<int, vector<int>, less<int> > q;
//最小堆
priority_queue<int, vector<int>, greater<int> > q;

 2.结构体优先级设置

法1:运算符重载

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)

跟cmp函数规则相反

return f1.price<f2.price; 价格高的优先级高

return f1.price>f2.price; 价格低的优先级高

法2:类似cmp函数

struct fruit
{
    string name;
    int    price;
};

struct cmp
{
     bool operator () (fruit f1,fruit f2){
        return f1.price < f2.price;//最大堆
    }
};
priority_queue<fruit, vector<fruit>, cmp> q;//最大堆,把less<>换成了cmp

 此时定义的类似cmp函数的struct结构体,跟重载效果一样

仍然与之前的cmp函数规则相反

即使是基本数据类型或者其他STL容器(例如set),

也可以通过同样的方式来定义优先级。 

如果结构体内的数据较为庞大(例如出现了字符串或者数组),建议使用引用来提高效率。

这时,比较类的参数中需要加上"const"和"&"

friend bool operator < (const fruit &f1,const fruit &f2) {
    return f1.price > f2.price;
}

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

二、常用函数:

(1) push()

入队操作,时间复杂度为O(logN)

q.push(x);

(2) top()

注意要先判空,防止队空导致错误

 获取堆顶元素(队首元素),时间复杂度为O(1)

cout<<q.top();

(3) pop()

注意要先判空,防止队空导致错误

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

q.pop();

(4) empty()

检测优先队列是否为空,

返回true则空,返回false则非空

时间复杂度为O(1)

if(!q.empty()){
    printf("Not Empty.\n");
}

(5) size()

返回优先队列中的元素个数,时间复杂度为O(1) 

 三、常见用途

  • 解决一些贪心问题
  • 对dijkstra算法进行优化(优先队列的本质是堆)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值