毋意,毋必,毋固,毋我。 言必行,行必果。
C++STL priority_queue 學習
本文來源自網上摘抄,故學習記錄於此。
包含priority_queue 的標頭檔是 <queue>
priority_queue類的主要成員:
priority_queue(); //預設建構函式,產生一個空的排序隊列
priority_queue(const queue&); //拷貝建構函式
priority_queue& operator=(const priority_queue &); //賦值運算子多載
priority_queue 的私人成員:
value_type; //priority_queue中存放的物件類型,它和priority_queue中的T類型相同
priority_queue(const Compare& comp); //構造產生一個空的priority_queue對象,使用comp作為priority_queue的comparison
priority_queue(const value_type* first, const value_type* last); //帶有兩個參數的構造 函數,使用預設的Comparison作為第三個參數
size_type; //正整數類型,和Sequence::size_type類型一樣。
bool empty() const; //判斷優先順序隊列是否為空白,為空白返回true,否則返回false
size_type size() const; //返回優先順序隊列中的元素個數
const value_type& top() const(); //返回優先順序隊列中第一個元素的參考值。
void push(const value_type& x); //把元素x插入到優先順序隊列的尾部,隊列的長度加1
void pop(); //刪除優先順序隊列的第一個值,前提是隊列非空,刪除後隊列長度減1
priority_queue<Type, Container, Functional>
如果我們把後面倆個參數預設的話,優先隊列就是大頂堆,隊頭元素最大。(這點由上面的程式可以看出)
Parameter |
Description |
Default |
T |
The type of object stored in the priority queue. |
|
Sequence |
The type of the underlying container used to implement the priority queue. |
vector<T> |
Compare |
The comparison function used to determine whether one element is smaller than another element. If Comparex,y) is true, then x is smaller than y. The element returned by Q.top) is the largest element in the priority queue. That is, it has the property that, for every other element x in the priority queue, Compare(Q.top(), x) is false. |
less<T> |
自訂類型重載 operator< 後,聲明對象時就可以只帶一個模板參數。
但此時不能像基本類型這樣聲明
priority_queue<Node, vector<Node>, greater<Node> >;
原因是 greater<Node> 沒有定義,如果想用這種方法定義
則可以按如下方式:
#include <iostream>
#include <queue>
using namespace std;
struct Node
{
int x,y;
Node(int a = 0,int b = 0):x(a),y(b){}
};
struct cmp
{
bool operator()(Node a,Node b){
if (a.x == b.x)
return a.y>b.y;
return a.x>b.x;
}
};
int main(){
priority_queue<Node,vector<Node>,cmp > q;
for (int i = 0; i < 10;++i)
{
q.push(Node(rand(),rand()));
}
while (!q.empty())
{
cout<<q.top().x<<" "<<q.top().y<<endl;
q.pop();
}
return EXIT_SUCCESS;
}
其實就三種用法
第一種,直接使用預設的。
它的模板聲明帶有三個參數,priority_queue<Type, Container, Functional>
Type 為資料類型, Container 為儲存資料的容器,Functional 為元素比較方式。
Container 必須是用數組實現的容器,比如 vector, deque 但不能用 list.
STL裡面預設用的是 vector. 比較方式預設用 operator< , 所以如果你把後面倆個
參數預設的話,優先隊列就是大頂堆,隊頭元素最大。
看例子
priority_queue<int> qi;
int a[len] = {3,5,9,6,2};
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();
}
通過<操作符可知在整數中元素大的優先順序高。
故例子中輸出結果為:9 6 5 3 2
第二種:
第二種方法:
在樣本1中,如果我們要把元素從小到大輸出怎麼辦呢?
這時我們可以傳入一個比較函數,使用functional.h函數對象作為比較函數。
如果要用到小頂堆,則一般要把模板的三個參數都帶進去。
STL裡面定義了一個仿函數 greater<>,對於基本類型可以用這個仿函式宣告小頂堆
priority_queue<int, vector<int>, greater<int> >qi2;
對於自訂類型,則必須自己重載 operator< 或者自己寫仿函數
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
};
bool operator<( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x;
}
int main(){
priority_queue<Node> q;
for( int i= 0; i< 10; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return 0;
}
或者這樣定義也是能達到效果的:
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
friend operator<( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x;
}
};
自訂類型重載 operator< 後,聲明對象時就可以只帶一個模板參數。
但此時不能像基本類型這樣聲明
priority_queue<Node, vector<Node>, greater<Node> >;
原因是 greater<Node> 沒有定義,如果想用這種方法定義
則可以按如下方式
例子:
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int x, y;
Node( int a= 0, int b= 0 ):
x(a), y(b) {}
};
struct cmp{
bool operator() ( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x; }
};
int main(){
priority_queue<Node, vector<Node>, cmp> q;
for( int i= 0; i< 10; ++i )
q.push( Node( rand(), rand() ) );
while( !q.empty() ){
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
getchar();
return 0;
}
還有一點要注意的是priority_queue中的三個參數,後兩個可以省去,因為有預設參數,不過如果,有第三個參數的話,必定要寫第二個參數。