C++中std::priority_queue的使用小結(jié)
std::priority_queue 是 C++ STL 提供的 優(yōu)先隊列,它是一種 最大堆(默認情況下),可以用于高效地獲取當前最大(或最小)的元素。
1. 基本用法
(1) 頭文件
要使用 std::priority_queue,需要包含:
#include <queue> #include <vector> #include <iostream>
(2) 默認情況(最大堆)
默認情況下,std::priority_queue 是 最大堆,即 堆頂是最大元素:
std::priority_queue<int> pq; // 默認是最大堆
示例:
#include <iostream>
#include <queue>
int main() {
std::priority_queue<int> pq;
pq.push(10);
pq.push(30);
pq.push(20);
std::cout << "堆頂元素:" << pq.top() << std::endl; // 輸出 30
pq.pop(); // 移除 30
std::cout << "新的堆頂:" << pq.top() << std::endl; // 輸出 20
return 0;
}
? 特點
push()插入元素,自動維護最大堆。top()獲取當前最大元素(堆頂)。pop()移除堆頂元素(但不返回它)。size()獲取隊列大小。empty()檢查隊列是否為空。
2. 自定義最小堆
如果要實現(xiàn) 最小堆(堆頂是最小元素),可以用 std::greater<T>:
std::priority_queue<int, std::vector<int>, std::greater<int>> pq_min;
示例:
#include <iostream>
#include <queue>
int main() {
std::priority_queue<int, std::vector<int>, std::greater<int>> pq_min;
pq_min.push(10);
pq_min.push(30);
pq_min.push(20);
std::cout << "堆頂元素:" << pq_min.top() << std::endl; // 輸出 10
pq_min.pop();
std::cout << "新的堆頂:" << pq_min.top() << std::endl; // 輸出 20
return 0;
}
? 重點
std::greater<int>使priority_queue變成 最小堆。
3. 自定義比較函數(shù)(結(jié)構(gòu)體/仿函數(shù))
(1) 結(jié)構(gòu)體仿函數(shù)
struct Compare {
bool operator()(int a, int b) {
return a > b; // 最小堆(a > b 表示 a 在 b 下面)
}
};
std::priority_queue<int, std::vector<int>, Compare> pq;
示例:
#include <iostream>
#include <queue>
struct Compare {
bool operator()(int a, int b) {
return a > b; // 讓小的元素優(yōu)先級高
}
};
int main() {
std::priority_queue<int, std::vector<int>, Compare> pq;
pq.push(10);
pq.push(30);
pq.push(20);
std::cout << "堆頂元素:" << pq.top() << std::endl; // 輸出 10
pq.pop();
std::cout << "新的堆頂:" << pq.top() << std::endl; // 輸出 20
return 0;
}
? 優(yōu)點
- 適用于復雜的數(shù)據(jù)結(jié)構(gòu)(如
struct)。 - 允許靈活定義優(yōu)先級。
4. 處理結(jié)構(gòu)體類型
如果 priority_queue 存儲的是 自定義結(jié)構(gòu)體,需要提供比較規(guī)則。
(1) 按權(quán)重排序的任務調(diào)度
#include <iostream>
#include <queue>
struct Task {
int id;
int priority;
// 重載運算符,用于最大堆(優(yōu)先級大的優(yōu)先)
bool operator<(const Task& other) const {
return priority < other.priority; // 優(yōu)先級高的排前面
}
};
int main() {
std::priority_queue<Task> pq;
pq.push({1, 3});
pq.push({2, 5});
pq.push({3, 1});
std::cout << "最高優(yōu)先級任務 ID:" << pq.top().id << std::endl; // 輸出 2
pq.pop();
std::cout << "新的最高優(yōu)先級任務 ID:" << pq.top().id << std::endl; // 輸出 1
return 0;
}
? 特點
- 默認是最大堆,因此
operator<定義為 優(yōu)先級小的在下面。
(2) 使用自定義比較函數(shù)
如果不能修改 struct,可以使用 外部比較函數(shù):
struct CompareTask {
bool operator()(const Task& a, const Task& b) {
return a.priority > b.priority; // 最小堆
}
};
std::priority_queue<Task, std::vector<Task>, CompareTask> pq;
完整示例:
#include <iostream>
#include <queue>
struct Task {
int id;
int priority;
};
// 使 priority_queue 變成最小堆
struct CompareTask {
bool operator()(const Task& a, const Task& b) {
return a.priority > b.priority; // 小優(yōu)先級的任務優(yōu)先
}
};
int main() {
std::priority_queue<Task, std::vector<Task>, CompareTask> pq;
pq.push({1, 3});
pq.push({2, 5});
pq.push({3, 1});
std::cout << "最高優(yōu)先級任務 ID:" << pq.top().id << std::endl; // 輸出 3
pq.pop();
std::cout << "新的最高優(yōu)先級任務 ID:" << pq.top().id << std::endl; // 輸出 1
return 0;
}
? 適用場景
- 優(yōu)先隊列調(diào)度算法
- 事件驅(qū)動仿真
- A 搜索(最短路徑算法)*
5. priority_queue 適用場景
| 應用場景 | 用法 |
|---|---|
| 最大堆(默認) | std::priority_queue<int> |
| 最小堆 | std::priority_queue<int, std::vector<int>, std::greater<int>> |
| 存儲結(jié)構(gòu)體(最大堆) | 結(jié)構(gòu)體重載 < |
| 存儲結(jié)構(gòu)體(最小堆) | std::greater<> 或自定義 Compare |
| K 大/小元素 | 維護大小為 K 的堆 |
| Dijkstra / A 搜索* | 結(jié)合 std::pair<int, int> 進行路徑計算 |
6. 經(jīng)典應用示例
(1) 找到前 K 個最大元素
#include <iostream>
#include <queue>
#include <vector>
void findTopK(std::vector<int>& nums, int k) {
std::priority_queue<int, std::vector<int>, std::greater<int>> pq; // 最小堆
for (int num : nums) {
pq.push(num);
if (pq.size() > k) pq.pop(); // 只保留 k 個最大值
}
std::cout << "前 " << k << " 個最大元素:" << pq.top() << std::endl;
}
int main() {
std::vector<int> nums = {3, 1, 5, 12, 2, 11};
findTopK(nums, 3); // 輸出 5
}
? 復雜度:O(N log K)
總結(jié)
std::priority_queue默認是 最大堆,可以用std::greater<>實現(xiàn) 最小堆。- 存儲結(jié)構(gòu)體時,可以使用 重載
<運算符 或 自定義比較器。 - 適用于 任務調(diào)度、路徑搜索(Dijkstra/A)等場景*。
到此這篇關(guān)于C++中std::priority_queue的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++ std::priority_queue的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VC++實現(xiàn)View內(nèi)容保存為圖片的方法
這篇文章主要介紹了VC++實現(xiàn)View內(nèi)容保存為圖片的方法,涉及VC++中Bitmap類的save方法相關(guān)使用技巧,需要的朋友可以參考下2016-08-08
利用ace的ACE_Task等類實現(xiàn)線程池的方法詳解
本篇文章是對利用ace的ACE_Task等類實現(xiàn)線程池的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05
一文讓你不再害怕指針之C指針詳解(經(jīng)典,非常詳細)
這篇文章主要給大家介紹了C指針的相關(guān)資料,文中介紹的很經(jīng)典,非常詳細,文中通過示例代碼介紹的非常詳細,對大家學習或者使用C指針具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-08-08
VC++ 字符串String MD5計算小工具 VS2008工程
基于字符串加密的MD5算法,VS2008 VC++,多字節(jié)編譯工程。主要代碼如下,實現(xiàn)了ANSI字符串加密與Unicode字符串加密,需要的朋友可以參考下2017-07-07

