優先級隊列是不同於先進先出隊列的另一種隊列。每次從隊列中取出的是具有最高優先權的元素
每個元素的優先級根據問題的要求而定。當從優先級隊列中刪除一個元素時,可能出現多個元素具有相同的優先權。在這種情況下,把這些具有相同優先權的元素視為一個先來先服務的隊列,按他們的入隊順序進行先后處理。
優先隊列是一種常用的數據結構,通常用堆實現,也可以用其他方式實現。
對應於大頂堆和小頂堆,存在最大優先隊列和最小優先隊列。以最大優先隊列為例,優先隊列除了具有堆上的一些操作,如調整堆, 構建堆之外,還有獲得優先隊列的最大元素,抽取出優先隊列的最大元素,向優先隊列中插入一個元素和增大優先隊列中某個元素的值。
一個優先隊列聲明的基本格式是:
priority_queue<結構類型> 隊列名;
如果默認的話,是less排序。
priority_queue <node> q; //node是一個結構體 //結構體里重載了‘<’小於符號 priority_queue <int,vector<int>,greater<int> > q; //不需要#include<vector>頭文件 //注意后面兩個“>”不要寫在一起,“>>”是右移運算符 priority_queue <int,vector<int>,less<int> >q;
q.size();//返回q里元素個數 q.empty();//返回q是否為空,空則返回1,否則返回0 q.push(k);//在q的末尾插入k q.pop();//刪掉q的第一個元素 q.top();//返回q的第一個元素 q.back();//返回q的末尾元素
如果對於隊列里元素是一個結構體類型,按照某一個屬性排序,就需要對比較函數進行重載
定義優先級的時候,直接在類中寫個friend 的操作符重載函數即可:
class node { public : int a; node(){} node( int x):a(x){} friend bool operator<( const node ne1, const node ne2)//參數也可以為引用,值傳遞 { if (ne1.a > ne2.a) { return true ; } else { return false ; } } };
其中在c++primer第三版 中文版中關於操作符重載有如下描述:"程序員只能為類類型或枚舉類型的操作數定義重載操作符我們可以這樣來實現把重載操作符聲明為類的成員或者聲明為名字空間成員同時至少有一個類或枚舉類型的參數按值傳遞或按引用傳遞"因此不可用指針類型的參數;
如果想定義指針類型的優先隊列,則需要另外你需要自定義一個自己的比較函數,在priority_queue的模板函數中,我們可以利用這樣一個template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> >模板,在我們的程序代碼中,則需要自己定義一個類來定義第三個模板參數,如:
class nodePointerComparer { public : nodePointerComparer(){} bool operator ()( const node* ne1, const node* ne2) const { return ne1->lessthan(ne2); } };
當然在這之前我們的類Node要重新書寫
class node { public : int a; node(){} node( int x):a(x){} bool lessthan( const node* pnode) const { return a < pnode->a; } };
int main() { priority_queue <node*, vector <node*>, nodePointerComparer> qn; node *n1 = new node(90); node *n2 = new node(2); node *n3 = new node(50); qn.push(n1); qn.push(n2); qn.push(n3); int size = qn.size(); for ( int i = 0; i < size; i++) { cout << qn.top()->a << endl; qn.pop(); } return 0; }
疑問之處:如果你使用第一種值傳遞的操作符重載,來實現第二種的指針類型優先隊列,是不會達到想要的結果的,個人理解是因為在指針類型的優先隊列中找“<”運算符的時候,重載的不是我們寫的值傳遞friend bool operator<(const node ne1,const node ne2)//
也就是沒有找到指針類型的"<"重載,所有不會達到優先隊列的效果。