C++中std::priority_queue的使用小結(jié)
std::priority_queue
是 C++ STL 提供的 優(yōu)先隊(duì)列,它是一種 最大堆(默認(rèn)情況下),可以用于高效地獲取當(dāng)前最大(或最小)的元素。
1. 基本用法
(1) 頭文件
要使用 std::priority_queue
,需要包含:
#include <queue> #include <vector> #include <iostream>
(2) 默認(rèn)情況(最大堆)
默認(rèn)情況下,std::priority_queue
是 最大堆,即 堆頂是最大元素:
std::priority_queue<int> pq; // 默認(rèn)是最大堆
示例:
#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; }
? 特點(diǎn)
push()
插入元素,自動(dòng)維護(hù)最大堆。top()
獲取當(dāng)前最大元素(堆頂)。pop()
移除堆頂元素(但不返回它)。size()
獲取隊(duì)列大小。empty()
檢查隊(duì)列是否為空。
2. 自定義最小堆
如果要實(shí)現(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; }
? 重點(diǎn)
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)先級(jí)高 } }; 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)點(diǎn)
- 適用于復(fù)雜的數(shù)據(jù)結(jié)構(gòu)(如
struct
)。 - 允許靈活定義優(yōu)先級(jí)。
4. 處理結(jié)構(gòu)體類型
如果 priority_queue
存儲(chǔ)的是 自定義結(jié)構(gòu)體,需要提供比較規(guī)則。
(1) 按權(quán)重排序的任務(wù)調(diào)度
#include <iostream> #include <queue> struct Task { int id; int priority; // 重載運(yùn)算符,用于最大堆(優(yōu)先級(jí)大的優(yōu)先) bool operator<(const Task& other) const { return priority < other.priority; // 優(yōu)先級(jí)高的排前面 } }; int main() { std::priority_queue<Task> pq; pq.push({1, 3}); pq.push({2, 5}); pq.push({3, 1}); std::cout << "最高優(yōu)先級(jí)任務(wù) ID:" << pq.top().id << std::endl; // 輸出 2 pq.pop(); std::cout << "新的最高優(yōu)先級(jí)任務(wù) ID:" << pq.top().id << std::endl; // 輸出 1 return 0; }
? 特點(diǎn)
- 默認(rèn)是最大堆,因此
operator<
定義為 優(yōu)先級(jí)小的在下面。
(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)先級(jí)的任務(wù)優(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)先級(jí)任務(wù) ID:" << pq.top().id << std::endl; // 輸出 3 pq.pop(); std::cout << "新的最高優(yōu)先級(jí)任務(wù) ID:" << pq.top().id << std::endl; // 輸出 1 return 0; }
? 適用場(chǎng)景
- 優(yōu)先隊(duì)列調(diào)度算法
- 事件驅(qū)動(dòng)仿真
- A 搜索(最短路徑算法)*
5. priority_queue 適用場(chǎng)景
應(yīng)用場(chǎng)景 | 用法 |
---|---|
最大堆(默認(rèn)) | std::priority_queue<int> |
最小堆 | std::priority_queue<int, std::vector<int>, std::greater<int>> |
存儲(chǔ)結(jié)構(gòu)體(最大堆) | 結(jié)構(gòu)體重載 < |
存儲(chǔ)結(jié)構(gòu)體(最小堆) | std::greater<> 或自定義 Compare |
K 大/小元素 | 維護(hù)大小為 K 的堆 |
Dijkstra / A 搜索* | 結(jié)合 std::pair<int, int> 進(jìn)行路徑計(jì)算 |
6. 經(jīng)典應(yīng)用示例
(1) 找到前 K 個(gè)最大元素
#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 個(gè)最大值 } std::cout << "前 " << k << " 個(gè)最大元素:" << pq.top() << std::endl; } int main() { std::vector<int> nums = {3, 1, 5, 12, 2, 11}; findTopK(nums, 3); // 輸出 5 }
? 復(fù)雜度:O(N log K)
總結(jié)
std::priority_queue
默認(rèn)是 最大堆,可以用std::greater<>
實(shí)現(xiàn) 最小堆。- 存儲(chǔ)結(jié)構(gòu)體時(shí),可以使用 重載
<
運(yùn)算符 或 自定義比較器。 - 適用于 任務(wù)調(diào)度、路徑搜索(Dijkstra/A)等場(chǎng)景*。
到此這篇關(guān)于C++中std::priority_queue的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++ std::priority_queue的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言限制鏈表最大長(zhǎng)度的方法實(shí)現(xiàn)
本文主要介紹了C語(yǔ)言中限制鏈表的長(zhǎng)度,通過(guò)在添加新元素時(shí)檢查鏈表的當(dāng)前長(zhǎng)度是否已經(jīng)達(dá)到預(yù)設(shè)的最大值來(lái)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2025-03-03C語(yǔ)言中怎么在main函數(shù)開始前執(zhí)行函數(shù)
C語(yǔ)言中怎么在main函數(shù)開始前執(zhí)行函數(shù)呢?下面小編就大家詳細(xì)的介紹一下。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-10-10淺談c++性能測(cè)試工具google benchmark
本文將會(huì)介紹如何使用模板以及參數(shù)生成器來(lái)批量生成測(cè)試用例,簡(jiǎn)化繁瑣的性能測(cè)試代碼2021-06-06C語(yǔ)言三個(gè)函數(shù)的模擬實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三個(gè)函數(shù)的模擬實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03