Priority_queue


  優先隊列是一種容器適配器(容器適配器的概念本人不會解釋,故此處無法作出說明),它的第一個元素(位於頭部top)總是隊列中最大的元素,這里的“最大”是指隊列元素的嚴格弱序中的“最大”。嚴格弱序是一系列數或事物按照一定的比較關系“<”排列得出的序列,“<”可以是數學中進行數值比較的大於,也可以是小於,還可以是其它含義,這大概與離散數學中的“偏序關系”相仿。

    在內存充足的情況下,優先隊列能被無限地插入元素。

    優先隊列作為一個容器適配器,它使用其它容器作為底層容器,並提供一系列訪問元素的函數。優先隊列中的元素從底層容器的“尾部(back)”彈出,即是從隊列的頂部(top)彈出。底層容器需要滿足的條件是可以通過迭代器隨機訪問其中的元素並且支持以下的操作:

  • front()
  • push_back()
  • pop_back()

故此,容器vector和deque可以作為底層容器,在創建優先隊列時若沒有聲明使用何種容器,則默認使用vector。

創建一個優先隊列的格式:

priority_queue<T, Container, Compare>

    可以看出,創建一個優先隊列默認需要三個參數(實際應用上有些參數可以省去)。參數解釋:

   T隊列中元素的數據類型

   Container: 用於儲存和訪問隊列元素的底層容器的類型。

   Compare: 比較關系,默認是數值上的小於關系,比如1<2,6<7,此時隊列中元素由隊頭到隊由大到小排列,采用默認compare時此參數可以省去。當需要采用其它標准進行比較時需要額外定義這一比較方式(下例示)。當滿足比較關系”<”時,返回true,否則返回false。

  創建優先隊列的一個例子:

View Code
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 
 5 class cmp
 6 {
 7 public:
 8    bool operator() (const int a,const int b)
 9    {
10        return a>b;
11    }
12 };
13 
14 int main()
15 {
16     priority_queue<int,vector<int>,cmp>que1;
17     priority_queue<int,vector<int> >que2;
18     int a[]={1,3,4,2,5,0,6};
19     for(int i=0;i<7;i++)
20     {
21         que1.push(a[i]);
22         que2.push(a[i]);
23 }
24     cout<<"que1:";
25     while(!que1.empty())
26     {
27         cout<<que1.top()<<" ";
28         que1.pop();
29     }
30     cout<<endl<<"que2:";
31     while(!que2.empty())
32     {
33         cout<<que2.top()<<" ";
34         que2.pop();
35     }
36     return 0;
37 }

  輸出結果:

que1:0 1 2 3 4 5 6

que2:6 5 4 3 2 1 0

  上例中que1使用比較方式cmp類,隊列中元素由小到大排列,而que2使用默認形式的“<”,元素按照優先級排列,隊頭元素最大。

  優先隊列成員函數(除構造函數、析構函數)簡介:

(1)priority_queue::empty

判斷隊列是否為空(也即是size是否為0),是則返回true,否則返回false。優先隊列的此成員函數實際上調用底層容器的同名函數。

(2)priority_queue::size

返回隊列中元素的個數。此函數實際上調用底層容器的同名函數。這個函數也可以用於判斷隊列是否為空。

(3)priority_queue::top

返回隊頭元素的常引用,隊頭元素是在所設定的比較關系下最大也即優先級最高的元素。此函數實際上調用底層容器的front函數。

(4)priority_queue::pop

清除隊頭元素。

(5)priority_queue::push

給隊列插入元素,新元素會按其優先級被排列到適當位置。

注:對於自定義類型比如結構體,必須重載<才能進行比較。見下例:

View Code
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 
 5 class Node
 6 {
 7 public:
 8     int idx;
 9     static int cnt;
10     Node()
11     {
12         idx=cnt++;
13     }
14 }a[10];
15 
16 int Node::cnt=1;
17 
18 bool operator < (Node a,Node b)
19 {
20     return a.idx>b.idx;
21 }
22 
23 int main()
24 {
25 //省略container和compare參數,此時container默認使用vector,而compare默認使用<,而<已經重載,於是可以按照自定義方式比較。
26     priority_queue<Node>que;//省略container和compare參數
27     for(int i=0;i<10;i++)
28         que.push(a[i]);
29     while(!que.empty())
30     {
31         cout<<que.top().idx<<" ";
32         que.pop();
33     }
34     return 0;
35 }

結果:1 2 3 4 5 6 7 8 9 10 

  若將上述重載<函數中的return a.idx>b.idx;改為return a.idx<b.idx;則輸出:10 9 8 7 6 5 4 3 2 1

可以看出,利用自定義compare可以使得優先隊列按照某些所需要的規則排序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM