優先隊列Priority Queues使用手冊

優先隊列容器默認使用向量容器實現,用戶也可以使用雙端隊列容器。優先隊列總是把優先級最高的元素放在隊列的最前方,來保持隊列的有序性。

插入操作push()使用一個雙變量的布爾函數,將隊列中的元素重新排序,以滿足這個要求。

該函數可以由用戶提供,否則可以使用<操作符,元素越大,優先級越高。

如果元素越小,優先級越高,則需要使用函數對象greater,表明在決定向優先級隊列中插入新元素時,push()應該使用的操作符是>而不是<.

 

 成員函數:

empty    
true if the priority queue has no elements

pop    
removes the top element of a priority queue

push    
adds an element to the end of the priority queue

size    
returns the number of items in the priority queue

top    
returns the top element of the priority queue

 

在優先隊列中,優先級高的元素先出隊列。標準庫默認使用元素類型的<操作符來確定它們之間的優先級關係。

優先隊列的第一種用法,也是最常用的用法:

priority_queue<int> qi;
通過<操作符可知在整數中元素大的優先級高。

故示例1中輸出結果爲:9 6 5 3 2

第二種方法:

在示例1中,如果我們要把元素從小到大輸出怎麼辦呢?

這時我們可以傳入一個比較函數,使用functional.h函數對象作爲比較函數。

priority_queue<int, vector<int>, greater<int> > qi2;
其中

第二個參數爲容器類型。

第三個參數爲比較函數。

故示例2中輸出結果爲:2 3 5 6 9

第三種方法:自定義優先級。

struct node
{
    friend bool operator< (node n1, node n2)
    {
        return n1.priority < n2.priority;
    }
    int priority;
    int value;
};

在該結構中,value爲值,priority爲優先級。

通過自定義operator<操作符來比較元素中的優先級。

在示例3中輸出結果爲:

優先級  值

9          5

8          2

6          1

2          3

1          4

但如果結構定義如下:

struct node
{
    friend bool operator> (node n1, node n2)
    {
        return n1.priority > n2.priority;
    }
    int priority;
    int value;
};

則會編譯不過(G++編譯器)因爲標準庫默認使用元素類型的<操作符來確定它們之間的優先級關係。而且自定義類型的<操作符與>操作符並無直接聯繫,故會編譯不過。

//代碼清單

#include<iostream>
#include<functional>
#include<queue>
using namespace std;
struct node
{
    friend bool operator< (node n1, node n2)
    {
        return n1.priority < n2.priority;
    }
    int priority;
    int value;
};
int main()
{
    const int len = 5;
    int i;
    int a[len] = {3,5,9,6,2};
    //示例1
    priority_queue<int> qi;
    for(i = 0; i < len; i++)
        qi.push(a[i]);
    for(i = 0; i < len; i++)
    {
        cout<<qi.top()<<" ";
        qi.pop();
    }
    cout<<endl;
    //示例2
    priority_queue<int, vector<int>, greater<int> >qi2;
    for(i = 0; i < len; i++)
        qi2.push(a[i]);
    for(i = 0; i < len; i++)
    {
        cout<<qi2.top()<<" ";
        qi2.pop();
    }
    cout<<endl;
    //示例3
    priority_queue<node> qn;
    node b[len];
    b[0].priority = 6; b[0].value = 1; 
    b[1].priority = 9; b[1].value = 5; 
    b[2].priority = 2; b[2].value = 3; 
    b[3].priority = 8; b[3].value = 2; 
    b[4].priority = 1; b[4].value = 4; 
    
    for(i = 0; i < len; i++)
        qn.push(b[i]);
    cout<<"優先級"<<'\t'<<"值"<<endl;
    for(i = 0; i < len; i++)
    {
        cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
        qn.pop();
    }
    return 0;
}

 另外貼一段優先隊列使用的代碼:

#include<iostream>
#include<functional>
#include<queue>
#include<vector>
using namespace std;
 
 
struct cmp1
{
    bool operator () (int &a, int &b)
    {
        return a > b ;              // 從小到大排序,值 小的 優先級別高
    }
};
 
struct cmp2
{
    bool operator () (int &a, int &b)
    {
        return a < b;             // 從大到小
    }
};
 
struct number1
{
    int x;
    bool operator < (const number1 &a)const 
    {
        return x > a.x;         // 從小到大  ,x 小的 優先級別高
    }
};
 
struct number2
{
    int x;
    bool operator < (const number2 &a)const
    {
        return x < a.x;            // 從大到小  ,x 大的優先級別高
    }
};
 
int a[] = {14,10,56,7,83,22,36,91,3,47,72,0};
number1 num1[] ={14,10,56,7,83,22,36,91,3,47,72,0};
number2 num2[] ={14,10,56,7,83,22,36,91,3,47,72,0};
 
int main()
{
    priority_queue<int>que;  // 採用默認優先級構造隊列  從大到小。 
 
    priority_queue<int, vector<int>, cmp1 >que1;
    priority_queue<int, vector<int>, cmp2 >que2;
 
    priority_queue<int, vector<int>, greater<int> > que3;  //functional 頭文件自帶的 
    priority_queue<int, vector<int>, less<int> > que4;      //functional 頭文件自帶的 
 
    priority_queue<number1> que5;
    priority_queue<number2> que6;
 
 
    int i;
    for(i=0;a[i];i++)
    {
        que.push(a[i]);
        que1.push(a[i]);
        que2.push(a[i]);
        que3.push(a[i]);
        que4.push(a[i]);
 
    }
 
     for(i=0;num1[i].x;i++)
         que5.push(num1[i]);
     for(i=0;num2[i].x;i++) 
         que6.push(num2[i]);
 
    printf("採用默認優先關係:\n(priority_queue<int>que;)\n");
    printf("Queue 0:\n");
        while(!que.empty())
    {
        printf("%3d",que.top());
        que.pop();
    }
    puts("");
    puts("");
    
    printf("採用結構體自定義優先級方式一:\n(priority_queue<int,vector<int>,cmp>que;)\n");
    printf("Queue 1:\n");
    while(!que1.empty())
    {
        printf("%3d",que1.top());
        que1.pop();
    }
    puts("");
 
    printf("Queue 2:\n");
        while(!que2.empty())
    {
        printf("%3d",que2.top());
        que2.pop();
    }
    puts("");
    puts("");
 
    printf("採用頭文件\"functional\"內定義優先級:\n(priority_queue<int, vector<int>,greater<int>/less<int> >que;)\n");
    printf("Queue 3:\n");
    while(!que3.empty())
    {
        printf("%3d",que3.top());
        que3.pop();
    }
    puts("");
 
    printf("Queue 4 :\n");
    while(!que4.empty())
    {
        printf("%3d",que4.top());
        que4.pop();
    }
    puts("");
    puts("");
 
    printf("採用結構體自定義優先級方式二:\n(priority_queue<number>que)\n");
    printf("Queue 5:\n");
    while(!que5.empty())
    {
        printf("%3d",que5.top());
        que5.pop();
    }
    puts("");
 
    printf("Queue 6:\n");
    while(!que6.empty())
    {
        printf("%3d",que6.top());
        que6.pop();
    }
 
    return 0;
}

執行結果:


 

 

九月網易有道招聘上機題:

給出大小爲N的數組,用最快的辦法找出前M個大的數字。

#include <iostream>
#include <functional>
#include <queue>
 
using namespace std;
 
int main()
{
    priority_queue<int,vector<int>, greater<int> > q;//從小到大
    int n,m,num;
    while (cin>>n>>m)
    {
        int i;
        for (i = 0; i < m; i ++)
        {
            cin>>num;
            q.push(num);
        }
        for (; i < n; i ++)
        {
            cin>>num;
            if (num > q.top())
            {
                q.pop();
                q.push(num);
            }
        }
        while (!q.empty())
        {
            cout<<q.top()<<" ";
            q.pop();
        }
        cout<<endl;
    }
    return 0;
}
 

這個題目可以用一個大小是M的最小堆來實現,初始建堆用數組前M個建好後,如果後面的元素a[i] 大於堆頂元素,那麼就刪除堆頂,插入新的元素。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章