详解C++的优先级队列(priority_queue)

使用时包含头文件#include<queue>
常用于排序问题,将优先级高的先输出

基本操作

和queue相同

top(): 访问队头元素
empty(): 队列是否为空
size(): 返回队列内元素个数
push ():插入元素到队尾 (并排序)
emplace(): 原地构造一个元素并插入队列
pop(): 弹出队头元素
swap(): 交换内容

定义比较函数

priority_queue定义:priority_queue<Type, Container, Function>

  • Type: 定义队列元素类型,可以是基本数据类型,也可以是复杂数据类型(对象)
  • Container:容器类型,即优先级队列基于什么数据类型来实现,可以是vector或者deque,默认情况下是vector
  • Function:指比较函数,用来指定构造的是大顶堆(元素从大到小输出)还是小顶堆(元素从小到大输出),基本元素可以使用less或者greater函数,但是对于对象这种负责结构,需要自己设计比较规则。

演示greater和less

小贴士:对于经常记混less和greater哪个是大顶堆哪个是小顶堆的童鞋,可以这样记,less和greater都是英文单词(little,great)的比较级,既然是比较级,那我们可以这样记(以less为例),理解为后一个比前一个小(越来越小),便可以轻松记住。

#include<iostream>
#include<queue>
using namespace std;

int main(){
    //默认
    priority_queue<int>q1;
    //大顶堆,从大到小排列
    priority_queue<int,vector<int>,less<int>>q2;
    //小顶堆,从小到大排列
    priority_queue<int,vector<int>,greater<int>>q3;
    for (int i = 0; i < 6; i++)
    {
        q1.push(i);
        q2.push(i);
        q3.push(i);
    }
    cout<<"q1队列(默认排序):"<<endl;
    while(!q1.empty()){
        cout<<q1.top()<<'\t';
        q1.pop();
    }
    cout<<"\nq2队列(less):"<<endl;
    while(!q2.empty()){
        cout<<q2.top()<<'\t';
        q2.pop();
    }
    cout<<"\nq3队列(greater):"<<endl;
    while(!q3.empty()){
        cout<<q3.top()<<'\t';
        q3.pop();
    }
    cout<<'\n';
    system("pause");
    return 0;
}

输出结果:

q1队列(默认排序):
5 4 3 2 1 0
q2队列(less):
5 4 3 2 1 0
q3队列(greater):
0 1 2 3 4 5

自定义比较函数

前面的greater<>和less<>只适用于基本类型的元素(int long char…),对于复杂数据类型需要自己定义比较规则。

方法1:过载运算符

先看实现方式

#include<iostream>
#include<queue>
using namespace std;
//运算符重载<
struct obg1
{
    int x;
    obg1(int a) {x = a;}
    bool operator<(const obg1& a) const
    {
        return x < a.x; //大顶堆
    }
};

int main(){
    obg1 test1(2);
    obg1 test2(3);
    obg1 test3(4);
    obg1 test4(4);
    priority_queue<obg1>q;
    q.push(test1);
    q.push(test2);
    q.push(test3);
    q.push(test4);
    while(!q.empty()){
        cout<<q.top().x<<"\t";
        q.pop();
    }
    system("pause");
    return 0;
}

输出结果:

4 4 3 2

在obg数据结构中,过载了运算符“<”,可以简单的这样理解,对于x<y,如果返回true,即y>x成立,则x和y在优先级队列中会交换位置,即数值大的在前,数值小的在后,也就是大顶堆。同理,小顶堆只需将x<y改成x>y即可。

方法2:过载()

直接上代码

#include<iostream>
#include<queue>
using namespace std;

struct obg1//运算符重载<
{
    int x;
    obg1(int a) {x = a;}
};
struct comp //重写函数
{
    bool operator() (obg1 a, obg1 b) 
    {
        return a.x < b.x; //大顶堆
    }
};

int main(){
    obg1 test1(2);
    obg1 test2(3);
    obg1 test3(4);
    obg1 test4(4);
    priority_queue<obg1,vector<obg1>,comp>q;
    q.push(test1);
    q.push(test2);
    q.push(test3);
    q.push(test4);
    while(!q.empty()){
        cout<<q.top().x<<"\t";
        q.pop();
    }
    system("pause");
    return 0;
}

输出结果:

4 4 3 2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三喂树屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值