STL Priority_Queue
priority_queue 調(diào)用 STL里面的 make_heap(), pop_heap(), push_heap() 算法
實(shí)現(xiàn),也算是堆的另外一種形式。
先寫一個(gè)用 STL 里面堆算法實(shí)現(xiàn)的與真正的STL里面的 priority_queue? 用法相
似的 priority_queue, 以加深對 priority_queue 的理解
#include?<iostream>
#include?<algorithm>
#include?<vector>
using?namespace?std;
class?priority_queue
{
????private:
????????vector<int>?data;
????????
????public:
????????void?push(?int?t?){?
????????????data.push_back(t);?
????????????push_heap(?data.begin(),?data.end());?
????????}
????????
????????void?pop(){
????????????pop_heap(?data.begin(),?data.end()?);
????????????data.pop_back();
????????}
????????
????????int?top()????{?return?data.front();?}
????????int?size()???{?return?data.size();??}
????????bool?empty()?{?return?data.empty();?}
};
int?main()
{
????priority_queue??test;
????test.push(?3?);
????test.push(?5?);
????test.push(?2?);
????test.push(?4?);
????
????while(?!test.empty()?){
????????cout?<<?test.top()?<<?endl;
????????test.pop();?}
????????
????return?0;
}
STL里面的 priority_queue 寫法與此相似,只是增加了模板及相關(guān)的迭代器什么的。
priority_queue 對于基本類型的使用方法相對簡單。
他的模板聲明帶有三個(gè)參數(shù),priority_queue<Type, Container, Functional>
Type 為數(shù)據(jù)類型, Container 為保存數(shù)據(jù)的容器,Functional 為元素比較方式。
Container 必須是用數(shù)組實(shí)現(xiàn)的容器,比如 vector, deque 但不能用 list.
STL里面默認(rèn)用的是 vector. 比較方式默認(rèn)用 operator< , 所以如果你把后面?zhèn)z個(gè)
參數(shù)缺省的話,優(yōu)先隊(duì)列就是大頂堆,隊(duì)頭元素最大。
看例子
#include?<iostream>
#include?<queue>
using?namespace?std;
int?main(){
????priority_queue<int>?q;
????
????for(?int?i=?0;?i<?10;?++i?)?q.push(?rand()?);
????while(?!q.empty()?){
????????cout?<<?q.top()?<<?endl;
????????q.pop();
????}
????
????getchar();
????return?0;
}
如果要用到小頂堆,則一般要把模板的三個(gè)參數(shù)都帶進(jìn)去。
STL里面定義了一個(gè)仿函數(shù) greater<>,對于基本類型可以用這個(gè)仿函數(shù)聲明小頂堆
例子:
#include?<iostream>
#include?<queue>
using?namespace?std;
int?main(){
????priority_queue<int,?vector<int>,?greater<int>?>?q;
????
????for(?int?i=?0;?i<?10;?++i?)?q.push(?rand()?);
????while(?!q.empty()?){
????????cout?<<?q.top()?<<?endl;
????????q.pop();
????}
????
????getchar();
????return?0;
}
?對于自定義類型,則必須自己重載 operator< 或者自己寫仿函數(shù)
先看看例子:
#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;
}
自定義類型重載 operator< 后,聲明對象時(shí)就可以只帶一個(gè)模板參數(shù)。
但此時(shí)不能像基本類型這樣聲明
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
在優(yōu)先隊(duì)列中,優(yōu)先級高的元素先出隊(duì)列。
標(biāo)準(zhǔn)庫默認(rèn)使用元素類型的<操作符來確定它們之間的優(yōu)先級關(guān)系。
優(yōu)先隊(duì)列的第一種用法,也是最常用的用法:
通過<操作符可知在整數(shù)中元素大的優(yōu)先級高。
故示例1中輸出結(jié)果為:9 6 5 3 2
第二種方法:
在示例1中,如果我們要把元素從小到大輸出怎么辦呢?
這時(shí)我們可以傳入一個(gè)比較函數(shù),使用functional.h函數(shù)對象作為比較函數(shù)。
其中
第二個(gè)參數(shù)為容器類型。
第二個(gè)參數(shù)為比較函數(shù)。
故示例2中輸出結(jié)果為:2 3 5 6 9
第三種方法:
自定義優(yōu)先級。
{
????friend?bool?operator<?(node?n1,?node?n2)
????{
????????return?n1.priority?<?n2.priority;
????}
????int?priority;
????int?value;
};
在該結(jié)構(gòu)中,value為值,priority為優(yōu)先級。
通過自定義operator<操作符來比較元素中的優(yōu)先級。
在示例3中輸出結(jié)果為:
優(yōu)先級? 值
9?????? ???5
8????????? 2
6??????????1
2??????????3
1??????????4
但如果結(jié)構(gòu)定義如下:
{
????friend?bool?operator>?(node?n1,?node?n2)
????{
????????return?n1.priority?>?n2.priority;
????}
????int?priority;
????int?value;
};
則會編譯不過(G++編譯器)
因?yàn)闃?biāo)準(zhǔn)庫默認(rèn)使用元素類型的<操作符來確定它們之間的優(yōu)先級關(guān)系。
而且自定義類型的<操作符與>操作符并無直接聯(lián)系,故會編譯不過。
//代碼清單
?
#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<<"優(yōu)先級"<<'\t'<<"值"<<endl;
????for(i?=?0;?i?<?len;?i++)
????{
????????cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
????????qn.pop();
????}
????return?0;
}
總結(jié)
以上是生活随笔為你收集整理的STL Priority_Queue的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ms 两个数组,从每个数组中取一个数相加
- 下一篇: struct 与 class区别