优先队列priority_queue的排序(c++版贼全一看就会)

本文解释了C++中的优先队列(priority_queue)及其默认行为,区分了大根堆和小根堆的区别,以及如何针对pair和自定义结构体进行排序,包括内部重载比较函数和外部cmp方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先我们需要知道优先队列priority_queue分为大根(顶)堆和小根(顶)堆(很久前看到一个博主说大顶堆是小根堆......让我把这个搞混了好久,以至于看优先队列的时候有些博主说默认大根堆,有些说默认大顶堆让我搞不明白了)

然后

priority_queue<int> q

这是默认写法,也可以写成

priority_queue <int,vector<int>,less<int> >q

这是大根堆,意思是输出的时候从根输出,而根是大的,所以输出是从大到小的。

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

则是小根堆,要记住带上greater的是小,反过来的。

然后就是优先队列的内部排序了,我们将它分为两类。

一类是以pair和int等常见的数据类型(可以默认,也可以自己写比较方法)

一类是自己定义的结构体(因为pair有first,second关系,而结构体没有先后关系,所以必须自己写比较方法,不能默认,而结构体的比较方法又有内部重载大于小于号和外部cmp两种方式)

一.pair和int等基本数据类型

1.对pair排序,

(1)如果自己不写cmp的话,默认先以first排序再根据second

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main() 
{
    priority_queue<pair<int, int> > a;
    pair<int, int> b(1, 2);
    pair<int, int> c(1, 3);
    pair<int, int> d(2, 5);
    a.push(d);
    a.push(c);
    a.push(b);
    while (!a.empty()) 
    {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }
}

输出(这是大根堆)

2 5
1 3
1 2

(2)自定义cmp

cmp必须为类,然后重载内部的比较函数,比较函数的内部与通常的cmp写法一样

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct cmp {
    bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
        if (a.first != b.first) return a.first > b.first;
        else return a.second < b.second;   //根据first升序,second降序
    }
};
int main()
{
    priority_queue<pair<int, int>,vector<pair<int,int> >,cmp > a;
    pair<int, int> b(1, 2);
    pair<int, int> c(1, 3);
    pair<int, int> d(2, 5);
    a.push(d);
    a.push(c);
    a.push(b);
    while (!a.empty())
    {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }
}

输出

1 3
1 2
2 5

2.对基本数据类型排序

几乎只要用到默认和greater这两个

二.对自定义结构体排序

(1).在结构体内部重载大于小于号,这个重载也有两种方法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
struct node
{
    int x;
    int y;
    /*friend  bool operator > (const node& a, const node& b)  //法一,这里是小根堆,有greater,要重载大于号
    {
        if (a.x != b.x)
        {
            return a.x > b.x;
        }
        else
        {
            return a.y < b.y;
        }
    }*/
    bool operator > ( const node& b) const  //法二
    {
        if (x != b.x)
        {
            return x > b.x;
        }
        else
        {
            return y < b.y;
        }
    }
};
priority_queue<node,vector<node>,greater<node>>q;
signed main()
{
    q.push({ 5,4 });
    q.push({ 5,3 });
    q.push({ 1,2 });
    q.push({ 1,1 });
    q.push({ 3,3 });
    q.push({ 3,1 });
    while (!q.empty())
    {
        node t = q.top();
        q.pop();
        cout << t.x << " " << t.y << endl;
    }
}

(2)在外面写cmp,和pair的cmp长得一样

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
struct node
{
    int x;
    int y;
};
struct cmp {
    //通常这里尽量加const和&这两个,当数据量比较庞大时,提高效率 
    bool operator () (const node& a, const node& b)
    {
        if (a.x != b.x)
        {
            return a.x > b.x;
        }
        else
        {
            return a.y < b.y;
        }
    }
};
priority_queue<node,vector<node>,cmp>q;
signed main()
{
    q.push({ 5,4 });
    q.push({ 5,3 });
    q.push({ 1,2 });
    q.push({ 1,1 });
    q.push({ 3,3 });
    q.push({ 3,1 });
    while (!q.empty())
    {
        node t = q.top();
        q.pop();
        cout << t.x << " " << t.y << endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值