priority_queue 基本介紹
priority_queue 是 STL queue 中一部分。普通的隊列是一種先進先出的數據結構,元素在隊列尾追加,而從隊列頭刪除。在優先隊列中,元素被賦予優先級。當訪問元素時,具有最高優先級的元素最先刪除。優先隊列具有最高級先出 (first in, largest out)的行爲特徵。
priority_queue 和 queue 不同的就在於我們可以自定義其中數據的優先級, 讓優先級高的排在隊列前面,優先出隊。
優先隊列具有隊列的所有特性,包括隊列的基本操作,只是在這基礎上添加了內部的一個排序,它本質是一個堆實現的。
頭文件
和 queue 一樣,需要包含 #include <queue>。
同時,priority_queue 也是屬於標準命名空間,即 using namespace std。
定義方法
priority_queue<Type, Container, Functional> 變量名;
1、Type 就是數據類型。
2、Container 就是容器類型(Container 必須是用數組實現的容器,比如 vector,deque 等等,但不能用 list。STL裏面默認用的是vector)。
3、Functional 就是比較的方式。
//升序隊列,小頂堆
priority_queue <int, vector<int>, greater<int> > q;
//降序隊列,大頂堆
priority_queue <int, vector<int>, less<int> > q;
//greater和less是std實現的兩個仿函數(就是使一個類的使用看上去像一個函數。其實現就是類中實現一個operator(),這個類就有了類似函數的行爲,就是一個仿函數類了)
基本操作
priority_queue 的基本操作類似 STL stack。
加入數據
使用 push() 函數。
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main () {
std::priority_queue<int> mypq;
mypq.push(30); //隊列數據: 30
mypq.push(100); //隊列數據: 100 30
mypq.push(25); //隊列數據: 100 30 25
mypq.push(40); //隊列數據: 100 40 30 25
return 0;
}
獲取頂部數據
使用 top() 函數。
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main () {
std::priority_queue<int> mypq;
mypq.push(30); //隊列數據: 30
std::cout << mypq.top() << std::endl; //30
mypq.push(100); //隊列數據: 100 30
std::cout << mypq.top() << std::endl; //100
mypq.push(25); //隊列數據: 100 30 25
std::cout << mypq.top() << std::endl; //100
mypq.push(40); //隊列數據: 100 40 30 25
std::cout << mypq.top() << std::endl; //100
return 0;
}
刪除數據
使用 pop() 函數,只能刪除頂部元素。
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main () {
std::priority_queue<int> mypq;
mypq.push(30); //隊列數據: 30
std::cout << mypq.top() << std::endl; //30
mypq.push(100); //隊列數據: 100 30
std::cout << mypq.top() << std::endl; //100
mypq.pop(); //隊列數據: 30
mypq.push(25); //隊列數據: 30 25
std::cout << mypq.top() << std::endl; //30
mypq.push(40); //隊列數據: 40 30 25
std::cout << mypq.top() << std::endl; //40
return 0;
}
隊列中數據大小
使用 size() 函數。
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main () {
std::priority_queue<int> mypq;
mypq.push(30); //隊列數據: 30
std::cout << mypq.size() << std::endl; //1
mypq.push(100); //隊列數據: 100 30
std::cout << mypq.size() << std::endl; //2
mypq.push(25); //隊列數據: 100 30 25
std::cout << mypq.size() << std::endl; //3
mypq.push(40); //隊列數據: 100 40 30 25
std::cout << mypq.size() << std::endl; //4
return 0;
}
隊列是否爲空
使用 empty() 函數判斷。
#include <iostream> // std::cout
#include <queue> // std::priority_queue
int main () {
std::priority_queue<int> mypq;
mypq.push(30); //隊列數據: 30
mypq.push(100); //隊列數據: 100 30
mypq.push(25); //隊列數據: 100 30 25
mypq.push(40); //隊列數據: 100 40 30 25
int sum=0;
while (!mypq.empty()) {
sum += mypq.top();
mypq.pop();
}//sum最終結果爲100+40+30+25
return 0;
}
例子
C++ 內置數據類型
#include <iostream>
#include <queue>
#include <string>
using namespace std;
int main() {
//對於基礎類型 默認是大頂堆
priority_queue<int> big;
//等同於 priority_queue<int, vector<int>, less<int> > big;
//這裏一定要有空格,不然成了右移運算符↓↓
priority_queue<int, vector<int>, greater<int> > small; //這樣就是小頂堆
priority_queue<string> b;
for (int i = 0; i < 10; i++) {
big.push(i);
small.push(i);
}
while (!big.empty()) {
cout << big.top() << ' ';
big.pop();
}
cout << endl;
while (!small.empty()) {
cout << small.top() << ' ';
small.pop();
}
cout << endl;
b.push("abc");
b.push("abcd");
b.push("cbd");
while (!b.empty()) {
cout << b.top() << ' ';
b.pop();
}
cout << endl;
return 0;
}
運行結果如下圖。
pair 做爲數據
比較規則爲: 先比較 pair 第一個元素,第一個相等比較第二個。
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
int main() {
priority_queue<pair<int, int> > a;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty()) {
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
return 0;
}
運行結果如下圖所示。
自定義數據類型
#include <iostream>
#include <queue>
using namespace std;
//方法1
typedef struct _st1 {
int x;
_st1(int a) {x = a;}
bool operator<(const _st1& a) const {
//運算符重載<
return x < a.x; //大頂堆
}
} ST1;
//方法2
typedef struct _st2 {
//重寫仿函數
bool operator() (_st1 a, _st1 b) {
return a.x < b.x; //大頂堆
}
} ST2;
int main()
{
ST1 a(6);
ST1 b(2);
ST1 c(13);
priority_queue<ST1> d;
d.push(b);
d.push(c);
d.push(a);
while (!d.empty()) {
cout << d.top().x << endl;
d.pop();
}
cout << endl;
priority_queue<ST1, vector<ST1>, ST2> f;
f.push(b);
f.push(c);
f.push(a);
while (!f.empty()) {
cout << f.top().x << endl;
f.pop();
}
return 0;
}
運行結果如下圖所示。