一.解釋:
優先隊列是隊列的一種,不過它可以按照自定義的一種方式(數據的優先級)來對隊列中的數據進行動態的排序,每次的push和pop操作,隊列都會動態的調整,以達到我們預期的方式來存儲。
例如,將元素5 3 2 4 6依次push到優先隊列中,規定順序為從大到小並輸出,輸出順序為6 5 4 3 2
二.用法
1.頭文件
#include<queue>//與隊列相同,不必引入vector的頭文件
2.定義方式
priority_queue<int> p;//最大值優先,是大頂堆一種簡寫方式 priority_queue<int,vector<int>,greater<int>>q1;//最小值優先,小頂堆 priority_queue<int,vector<int>,less<int> >q2;//最大值優先,大頂堆 //其中第一個參數是數據類型,第二個參數為容器類型。第三個參數為比較函數。
在使用時,我們會有很多時間用到根據結構體的某一個元素進行排序,下面給出定義結構體的優先級比較方式
struct node { string name; int price; friend bool operator< (node a, node b) { return a.price < b.price; // 相當於less,這是大頂堆,反之則是小頂堆,最大值優先 } } stu; //定義結構體變量 這樣直接可以: priority_queue<node > q;
可以將比較運算符外置,方法如下
struct node { string name; int price; } stu; //定義結構體變量 struct cmp { bool operator () (node a, node b) // 重載括號 { return node.price < node.price; // 相當於less,大頂堆 } };
3.常用操作:
q.push(x) //將x加入隊列中,即入隊操作 q.pop() //出隊操作(刪除隊列首元素),只是出隊,沒有返回值 q.top() //返回第一個元素(隊首元素)優先隊列的隊首用top,而普通隊列的隊首用front q.size() //返回棧隊列中的元素個數 q.empty() //當隊列為空時,返回 true
三.舉例
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> #include <stack> #include <vector> 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<<"優先級"<<'\t'<<"值"<<endl; for(i = 0; i < len; i++) { cout<<qn.top().priority<<'\t'<<qn.top().value<<endl; qn.pop(); } return 0; }