<span style="font-family: Arial, Helvetica, sans-serif;">priority_queue 對於基本類型的使用方法相對簡單。他的模板聲明帶有三個參數, Type 為資料類型, Container 為儲存資料的容器,Functional 為元素比較方式。Container 必須是用數組實現的容器,比如 vector, deque 但不能用 list.STL裡面容器預設用的是 vector. 比較方式預設用 operator< , 所以如果你把後面倆個參數 預設的話,優先隊列就是大頂堆,隊頭元素最大。</span>
執行個體
#include <queue>using namespace std;int main(){ priority_queue<int,vector<int>,less<int> >q1;//使用priority_queue<int> q1;一樣,都是大根堆,沒錯,就是大根堆 for(int i=0;i<10;i++) q1.push(i); while(!q1.empty()){ cout<<q1.top()<< endl; q1.pop(); } return 0;} 如果要用到小頂堆,則一般要把模板的三個參數都帶進去。
STL裡面定義了一個仿函數 greater<>,對於基本類型可以用這個仿函式宣告小頂堆
例子: 變less<int> 為 greater<int>
#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(i); while(!q.empty()){ cout<<q.top()<< endl; q.pop(); } return 0;}
自訂類型,要重載運算子,由於priority_queue預設的是operator<,so 重載這個(記住。)
兩種是等價的
1:
#include <iostream>#include <queue>using namespace std;struct Node{int x, y;bool operator<( const Node &b)const//為什麼這麼多const(唯讀)和&(引用)<span style="font-family: Arial, Helvetica, sans-serif;"> 該問題在下文,會提到</span>
{ if(x==b.x) return y>b.y; return x>b.x;}//定義為成員函數,只有當運算子左邊為該結構體變數時,才起作用}node; int main(){ priority_queue<Node>q; for(int i=0;i<10;i++){ node.x=i; node.y=10-i/2; q.push(node); } while(!q.empty()){ cout<<q.top().x <<' '<<q.top().y<<endl; q.pop(); } return 0;}
2:
#include <iostream>#include <queue>using namespace std;struct Node{int x, y;}node; bool operator<( Node a, Node b){ if(a.x==b.x) return a.y>b.y; return a.x>b.x;}//在結構體外面定義,為全域名字空間的成員,定義在外面,運算子左邊的可以不是結構體變數,也就是說,此處前一個的Node 允許換為int
//同時,放在結構體外面,就不用放那些麻煩的const & int main(){ priority_queue<Node>q; for(int i=0;i<10;i++){ node.x=i; node.y=10-i/2; q.push(node); } while(!q.empty()){ cout<<q.top().x <<' '<<q.top().y<<endl; q.pop(); } return 0;}
C:如何決定把一個操作符重載為類成員函數還是全域名字空間的成員呢。
①如果一個重載操作符是類成員,那麼只有當與他一起使用的左運算元是該類的對象時,該操作符才會被調用。如果該操作符的左運算元必須是其他的類型,則操作符必須被重載為全域名字空間的成員。
②C++要求賦值=,下標[],調用(), 和成員指向-> 操作符必須被定義為類成員操作符。任何把這些操作符定義為名字空間成員的定義都會被標記為編譯時間刻錯誤。
③如果有一個運算元是類類型如string類的情形那麼對於對稱操作符比如等於操作符最好定義為全域名字空間成員。
注意:
以前一直有一個不明白的問題,對於sort來說,cmp函數只要是<,那麼就是小於,然後升序;>就是從大到小
但是看很多其他的定義來說,就不是這個樣子,和想象的相反
struct Node{<span style="white-space:pre"></span>int x, y;<span style="white-space:pre"></span>bool operator<( const Node &b)const<span style="white-space:pre"></span>{ <span style="white-space:pre"></span>if(x==b.x) return y>b.y;<span style="white-space:pre"></span>return x>b.x;<span style="white-space:pre"></span>}//例如這裡,這是上文優先隊列的重載,意思是說按x為第一關鍵字,y為第二關鍵字,的小根堆,但是注意上面是operator <
//下面就成了x>b.x,不對啊。事實上,優先隊列內部就是一個堆,裡面的運算子均為<,即預設的運算子,但是我們把他賦予了>的意義,為什麼要賦予>的意思n呢。因為,在priority_pueue內部,預設是大根堆,也就是說,如果根節點<span style="color:#ff0000;">小於</span>一個孩子的話,那麼交換(<就是用在這裡)我們把他要改為小根堆,那麼就是如果根節點大,才交換,<的符號沒變,只是代表了>而以。x呢就是運算子左邊的,b.x自然就是右邊的。
}node;
差不多明白了
不過那些cosnt 和& 是幹什麼的
認識一些概念
1. 比如你定義一個函數void add(int a, int b),這裡的a和b就是形參。
2. 當你進行函數調用的時候,add(1, 2),這裡的1和2就是實參。
bool operator<( const Node &b)const{ if(x==b.x) return y>b.y; return x>b.x;}
剛剛的問題,如果第一個const和&刪了,沒事;&刪了沒事;第二個const刪了就不行;
還有如果光是第一個const刪了(&不動),也會報錯
因為:如果使用參考型別的實參的唯一目的是為了避免大量的複製實參,而不對實參做修改,最好使用的形參類型為const 類型名&。這也就是為什麼上面用const node &b,所以,一定要加上,第二個const就直接背過即可。
詳見:http://blog.csdn.net/guiyinzhou/article/details/6298030 C++『const 引用 傳參』『類成員函數』
代碼寫的很屎,主要是練一下類的重載運算子,明白了const到底是幹嗎用的: [cpp] view plain copy print ? bool operator <(const point b)const{ return a.x<b.x; }
第一個const 保證b不被改變,第二個const 保證原變數不被改變。
寫這些大致想保證該不被改變的就不被改變吧(否則出現編譯錯誤)。。。。。。。。。。。。。