C++中priority_queue的實現(xiàn)
一、priority_queue 核心定義
std::priority_queue(優(yōu)先隊列)是 C++ STL 中的適配器容器(基于其他容器實現(xiàn)),本質是一個「堆結構」——隊列中的元素會按照優(yōu)先級自動排序,而非按插入順序。
- 核心特性:每次訪問/彈出的都是優(yōu)先級最高的元素(默認是最大值,可自定義為最小值);
- 底層實現(xiàn):默認基于
std::vector,也可指定std::deque(不支持std::list,因為堆需要隨機訪問); - 頭文件:必須包含
<queue>。
二、基本用法(默認大頂堆)
1. 初始化與核心操作
#include <iostream>
#include <queue> // 必須包含
using namespace std;
int main() {
// 1. 初始化:默認是大頂堆(最大值優(yōu)先)
priority_queue<int> pq;
// 2. 插入元素(push):O(log n) 復雜度
pq.push(3);
pq.push(1);
pq.push(5);
pq.push(2);
// 3. 訪問隊首(top):返回優(yōu)先級最高的元素(最大值)
cout << "隊首元素(最大值):" << pq.top() << endl; // 輸出:5
// 4. 彈出隊首(pop):刪除優(yōu)先級最高的元素,O(log n) 復雜度
pq.pop();
cout << "彈出后隊首:" << pq.top() << endl; // 輸出:3
// 5. 判空(empty)、大?。╯ize)
cout << "是否為空:" << (pq.empty() ? "是" : "否") << endl; // 輸出:否
cout << "元素個數(shù):" << pq.size() << endl; // 輸出:3
// 6. 遍歷(無迭代器,需彈出所有元素)
while (!pq.empty()) {
cout << pq.top() << " "; // 輸出:3 2 1
pq.pop();
}
return 0;
}2. 關鍵說明
top():僅返回隊首元素,不刪除;pop():僅刪除隊首元素,無返回值(需先top()再pop());- 無
clear()成員函數(shù):清空優(yōu)先隊列需手動彈出所有元素,或賦值空隊列(pq = priority_queue<int>();); - 不支持隨機訪問:無法直接訪問中間元素,只能通過
top()訪問隊首。
三、自定義優(yōu)先級(小頂堆/自定義規(guī)則)
默認的 priority_queue 是「大頂堆」(最大值優(yōu)先),可通過以下方式修改優(yōu)先級:
1. 實現(xiàn)小頂堆(最小值優(yōu)先)
方式1:指定比較函數(shù) greater<T>
#include <iostream>
#include <queue>
#include <vector> // 顯式指定底層容器
using namespace std;
int main() {
// 模板參數(shù):<元素類型, 底層容器類型, 比較函數(shù)>
priority_queue<int, vector<int>, greater<int>> pq;
pq.push(3);
pq.push(1);
pq.push(5);
pq.push(2);
cout << "小頂堆隊首(最小值):" << pq.top() << endl; // 輸出:1
pq.pop();
cout << "彈出后隊首:" << pq.top() << endl; // 輸出:2
return 0;
}
方式2:對元素取反(適用于簡單類型)
// 插入時取反,彈出時再取反,模擬小頂堆 priority_queue<int> pq; pq.push(-3); pq.push(-1); pq.push(-5); pq.push(-2); cout << "模擬小頂堆隊首:" << -pq.top() << endl; // 輸出:1
2. 自定義結構體/類的優(yōu)先級
需重載比較運算符(operator<),或自定義比較函數(shù)。
示例:結構體按指定字段排序
#include <iostream>
#include <queue>
#include <string>
using namespace std;
// 定義結構體:存儲學生姓名和分數(shù)
struct Student {
string name;
int score;
// 重載 < 運算符(注意:優(yōu)先隊列用 < 比較,且規(guī)則與直覺相反)
// 需求:分數(shù)高的優(yōu)先級高(大頂堆)
bool operator<(const Student& other) const {
// 若 this->score < other.score,則 other 優(yōu)先級更高
return score < other.score;
}
};
int main() {
priority_queue<Student> pq;
pq.push({"Alice", 85});
pq.push({"Bob", 92});
pq.push({"Charlie", 78});
// 輸出優(yōu)先級最高的元素(分數(shù)最高的Bob)
cout << "最高分:" << pq.top().name << " " << pq.top().score << endl; // Bob 92
pq.pop();
cout << "次高分:" << pq.top().name << " " << pq.top().score << endl; // Alice 85
return 0;
}
自定義比較函數(shù)(適用于復雜規(guī)則)
#include <iostream>
#include <queue>
#include <string>
#include <functional> // 需包含(for function)
using namespace std;
struct Student {
string name;
int score;
};
// 自定義比較函數(shù):分數(shù)低的優(yōu)先級高(小頂堆)
struct CompareStudent {
bool operator()(const Student& a, const Student& b) {
return a.score > b.score; // 與小頂堆的 greater 邏輯一致
}
};
int main() {
priority_queue<Student, vector<Student>, CompareStudent> pq;
pq.push({"Alice", 85});
pq.push({"Bob", 92});
pq.push({"Charlie", 78});
cout << "最低分:" << pq.top().name << " " << pq.top().score << endl; // Charlie 78
return 0;
}
四、底層原理:堆結構
priority_queue 的核心是二叉堆(完全二叉樹),所有操作均基于堆的特性:
- 插入(push):將元素添加到堆尾,然后「上?。╯ift up)」調整堆,確保父節(jié)點優(yōu)先級高于子節(jié)點(O(log n));
- 彈出(pop):將堆頂元素與堆尾元素交換,刪除堆尾,然后「下沉(sift down)」調整堆(O(log n));
- 訪問隊首(top):直接返回堆頂元素(O(1))。
五、常見應用場景
- Top K 問題:如找數(shù)組中前 K 大/前 K 小的元素(用小頂堆存前 K 大,大頂堆存前 K ?。?;
// 示例:找數(shù)組中前3大的元素 vector<int> nums = {5, 2, 9, 1, 7, 6, 8}; priority_queue<int, vector<int>, greater<int>> pq; // 小頂堆 for (int num : nums) { pq.push(num); if (pq.size() > 3) pq.pop(); // 保持堆大小為3 } // 此時堆中是前3大的元素(7,8,9),但順序是從小到大 - 貪心算法:如任務調度、哈夫曼編碼、最短路徑(Dijkstra 算法);
- 實時排序:需頻繁獲取最大值/最小值的場景(如事件優(yōu)先級處理)。
六、注意事項
- 底層容器限制:只能用支持隨機訪問的容器(
vector/deque),不能用list(無隨機訪問); - 比較函數(shù)規(guī)則:
- 默認
less<T>:大頂堆(a < b則 b 優(yōu)先級高); greater<T>:小頂堆(a > b則 b 優(yōu)先級高);
- 默認
- 性能:插入/彈出為 O(log n),訪問隊首為 O(1),遍歷需彈出所有元素(O(n log n));
- 線程安全:無內置線程安全,多線程需手動加鎖。
總結
| 核心特性 | 說明 |
|---|---|
| 排序規(guī)則 | 默認大頂堆,可自定義為小頂堆/自定義規(guī)則 |
| 核心操作 | push(插入)、top(查隊首)、pop(刪隊首) |
| 時間復雜度 | push/pop: O(log n),top: O(1) |
| 底層容器 | 默認 vector,可指定 deque |
| 適用場景 | Top K、貪心算法、實時優(yōu)先級處理 |
priority_queue 是 C++ 中處理「優(yōu)先級排序」的核心容器,重點掌握自定義優(yōu)先級的兩種方式(greater<T>/自定義比較函數(shù)),以及 Top K 問題的經典用法。
到此這篇關于C++中priority_queue的實現(xiàn)的文章就介紹到這了,更多相關C++ priority_queue內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- c++ priority_queue用法入門超詳細教程
- C++ 中"priority_queue" 優(yōu)先級隊列實例詳解
- c++中priority_queue模擬的實現(xiàn)
- 深入了解C++優(yōu)先隊列(priority_queue)的使用方法
- C++中priority_queue與仿函數(shù)實現(xiàn)方法
- C++中STL的優(yōu)先隊列priority_queue詳解
- C++中priority_queue模擬實現(xiàn)的代碼示例
- C++ 容器適配器priority_queue的使用及實現(xiàn)代碼
- 詳解c++優(yōu)先隊列priority_queue的用法
- 詳解C++模擬實現(xiàn)priority_queue(仿函數(shù))
- C++深入刨析優(yōu)先級隊列priority_queue的使用
相關文章
c++ std::sort使用自定義的比較函數(shù)排序方式
文章介紹了使用std::sort對容器內元素進行排序的基本方法,包括自定義排序函數(shù)和在類中調用自定義成員函數(shù)進行排序的方法,文章還指出了在傳遞成員函數(shù)指針時可能會遇到的錯誤,并提供了使用Lambda表達式的解決辦法2025-02-02
C語言輸入一個數(shù)判斷是否為素數(shù)的多種方法
素數(shù)是只能被1和它自己本身整除,不能被其他自然數(shù)整除的大于1的正整數(shù),下面這篇文章主要給大家介紹了關于C語言輸入一個數(shù)判斷是否為素數(shù)的多種方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-04-04
使用Qt實現(xiàn)監(jiān)聽網頁是否響應并導出Excel表
Qt導出數(shù)據(jù)到excel,方法有很多,下面這篇文章主要給大家介紹了關于使用Qt實現(xiàn)監(jiān)聽網頁是否響應并導出Excel表的相關資料,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下2023-11-11
C和C++中實現(xiàn)對數(shù)據(jù)的流加密RC4算法
文章介紹了RC4流密碼算法,涵蓋其概述、特點(高效、簡單、適用性廣)、原理(密鑰流生成與異或加密)、初始化步驟及C/C++實現(xiàn)代碼,強調實際應用需加強安全性,如密鑰管理與復雜加密庫的使用2025-10-10

