C++中std::priority_queue的使用小結
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ù)(結構體/仿函數(shù))
(1) 結構體仿函數(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ù)結構(如
struct)。 - 允許靈活定義優(yōu)先級。
4. 處理結構體類型
如果 priority_queue 存儲的是 自定義結構體,需要提供比較規(guī)則。
(1) 按權重排序的任務調(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)度算法
- 事件驅動仿真
- A 搜索(最短路徑算法)*
5. priority_queue 適用場景
| 應用場景 | 用法 |
|---|---|
| 最大堆(默認) | std::priority_queue<int> |
| 最小堆 | std::priority_queue<int, std::vector<int>, std::greater<int>> |
| 存儲結構體(最大堆) | 結構體重載 < |
| 存儲結構體(最小堆) | std::greater<> 或自定義 Compare |
| K 大/小元素 | 維護大小為 K 的堆 |
| Dijkstra / A 搜索* | 結合 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)
總結
std::priority_queue默認是 最大堆,可以用std::greater<>實現(xiàn) 最小堆。- 存儲結構體時,可以使用 重載
<運算符 或 自定義比較器。 - 適用于 任務調(diào)度、路徑搜索(Dijkstra/A)等場景*。
到此這篇關于C++中std::priority_queue的使用小結的文章就介紹到這了,更多相關C++ std::priority_queue的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言中怎么在main函數(shù)開始前執(zhí)行函數(shù)
C語言中怎么在main函數(shù)開始前執(zhí)行函數(shù)呢?下面小編就大家詳細的介紹一下。需要的朋友可以過來參考下,希望對大家有所幫助2013-10-10

