1. 程式人生 > >priority_queue優先佇列

priority_queue優先佇列


引入
優先佇列是一種特殊的佇列,在學習堆排序的時候就有所瞭解。

那麼優先佇列是什麼呢? 
說白了,就是一種功能強大的佇列。

它的功能強大在哪裡呢? 
四個字:自動排序。

優先佇列的標頭檔案&&宣告
首先,你需要

#include<queue>
using namespace std;


這兩個標頭檔案。

其次,一個優先佇列宣告的基本格式是: 
priority_queue<結構型別> 佇列名; 
比如:

priority_queue <int> i;
priority_queue <double> d;


不過,我們最為常用的是這幾種:

priority_queue <node> q;
//node是一個結構體
//結構體裡過載了‘<’小於符號
priority_queue <int,vector<int>,greater<int> > q;
//不需要#include<vector>標頭檔案
//注意後面兩個“>”不要寫在一起,“>>”是右移運算子
priority_queue <int,vector<int>,less<int> >q;


我們將在下文來講講這幾種宣告方式的不同。

優先佇列的基本操作
與佇列的基本操作如出一轍。 
如果想要了解請點選這裡,看關於佇列的介紹。

以一個名為q的優先佇列為例。

q.size();//返回q裡元素個數
q.empty();//返回q是否為空,空則返回1,否則返回0
q.push(k);//在q的末尾插入k
q.pop();//刪掉q的第一個元素
q.top();//返回q的第一個元素
q.back();//返回q的末尾元素



優先佇列的特性
上文已經說過了,自動排序。 
怎麼個排法呢? 
在這裡介紹一下:

預設的優先佇列(非結構體結構)

priority_queue <int> q;


這樣的優先佇列是怎樣的?讓我們寫程式驗證一下。

#include<cstdio>
#include<queue>
using namespace std;
priority_queue <int> q;
int main()
{
    q.push(10),q.push(8),q.push(12),q.push(14),q.push(6);
    while(!q.empty())
        printf("%d ",q.top()),q.pop();
}



程式大意就是在這個優先佇列裡依次插入10、8、12、14、6,再輸出。 
結果是什麼呢? 
14 12 10 8 6 
也就是說,它是按從大到小排序的!

預設的優先佇列(結構體,過載小於)
先看看這個結構體是什麼。

struct node
{
    int x,y;
    bool operator < (const node & a) const
    {
        return x<a.x;
    }
};



這個node結構體有兩個成員,x和y,它的小於規則是x小者小。 
再來看看驗證程式:

#include<cstdio>
#include<queue>
using namespace std;
struct node
{
    int x,y;
    bool operator < (const node & a) const
    {
        return x<a.x;
    }
}k;
priority_queue <node> q;
int main()
{
    k.x=10,k.y=100; q.push(k);
    k.x=12,k.y=60; q.push(k);
    k.x=14,k.y=40; q.push(k);
    k.x=6,k.y=80; q.push(k);
    k.x=8,k.y=20; q.push(k);
    while(!q.empty())
    {
        node m=q.top(); q.pop();
        printf("(%d,%d) ",m.x,m.y);
    }
}




程式大意就是插入(10,100),(12,60),(14,40),(6,20),(8,20)這五個node。 
再來看看它的輸出: 

(14,40) (12,60) (10,100) (8,20) (6,80)

它也是按照過載後的小於規則,從大到小排序的。

less和greater優先佇列
還是以int為例,先來宣告:

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


話不多說,上程式和結果:

#include<cstdio>
#include<queue>
using namespace std;
priority_queue <int,vector<int>,less<int> > p;
priority_queue <int,vector<int>,greater<int> > q;
int a[5]={10,12,14,6,8};
int main()
{
    for(int i=0;i<5;i++)
        p.push(a[i]),q.push(a[i]);

    printf("less<int>:")
    while(!p.empty())
        printf("%d ",p.top()),p.pop();  

    pritntf("\ngreater<int>:")
    while(!q.empty())
        printf("%d ",q.top()),q.pop();
}


結果: 

less<int>:14 12 10 8 6 
greater<int>:6 8 10 12 14

所以,我們可以知道,less是從大到小,greater是從小到大。

作個總結
為了裝13方便,在平時,建議大家寫:

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


平時如果用從大到小不用後面的vector<int>,less<int>,可能到時候要改成從小到大,你反而會搞忘怎麼寫greater<int>,反而得不償失。

例子

 

Fence Repair

https://blog.csdn.net/weixin_43272781/article/details/83050793