C++中priority_queue的使用與模擬實現(xiàn)
priority_queue的使用
priority_queue簡介
- 優(yōu)先隊列是一種容器適配器,有嚴格的排序標準,它的第一個元素總是它所包含的元素中最大的(或最小的)。
- 此上下文類似于堆,在堆中可以隨時插入元素,并且只能檢索最大堆(或 最小堆)元素(優(yōu)先隊列中位于頂部的元素)。
- 默認情況下,如果沒有為特定的priority_queue類實例化指定容器類,則使用vector。
priority_queue的使用
成員函數(shù) | 功能 |
---|---|
push | 插入數(shù)據(jù) |
pop | 刪除優(yōu)先級隊列中最大(最小)元素,即堆頂元素 |
top | 返回優(yōu)先級隊列中最大(最小)元素,即堆頂元素 |
empty | 檢測優(yōu)先級隊列是否為空 |
size | 獲取隊列中有效元素個數(shù) |
void TestPriorityQueue() { // 默認情況下,創(chuàng)建的是大堆,其底層按照小于號比較 vector<int> v{ 3, 2, 7, 6, 0, 4, 1, 9, 8, 5 }; priority_queue<int> q1;// 構(gòu)建優(yōu)先級隊列 for (auto e : v) q1.push(e);//尾插 cout << "q1中元素個數(shù):" << q1.size() << endl; for (size_t i = 0;i<v.size();++i) { cout << q1.top() << " ";//輸出棧頂?shù)臄?shù)據(jù) q1.pop();//尾刪 } cout << endl; cout << "q1中元素個數(shù):" << q1.size() << endl; cout << endl; // 如果要創(chuàng)建小堆,將第三個模板參數(shù)換成greater比較方式 priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end()); for (size_t i = 0; i<v.size(); ++i) { cout << q2.top() << " ";//輸出棧頂?shù)臄?shù)據(jù) q2.pop();//尾刪 } cout << endl; }
如果在priority_queue中放自定義類型的數(shù)據(jù),用戶需要在自定義類型中提供> 或者< 的重載。
class Date { public: Date(int year = 1900, int month = 1, int day = 1) : _year(year) , _month(month) , _day(day) {} bool operator<(const Date& d)const { return (_year < d._year) || (_year == d._year && _month < d._month) || (_year == d._year && _month == d._month && _day < d._day); } bool operator>(const Date& d)const { return (_year > d._year) || (_year == d._year && _month > d._month) || (_year == d._year && _month == d._month && _day > d._day); } friend ostream& operator<<(ostream& _cout, const Date& d) { _cout << d._year << "-" << d._month << "-" << d._day; return _cout; } private: int _year; int _month; int _day; }; void TestPriorityQueue() { // 大堆,需要用戶在自定義類型中提供<的重載 priority_queue<Date> q1; q1.push(Date(2022, 1, 7)); q1.push(Date(2022, 1, 1)); q1.push(Date(2022, 1, 31)); cout << q1.top() << endl; cout << endl; // 如果要創(chuàng)建小堆,需要用戶提供>的重載 priority_queue<Date, vector<Date>, greater<Date>> q2; q2.push(Date(2022, 1, 7)); q2.push(Date(2022, 1, 1)); q2.push(Date(2022, 1, 31)); cout << q2.top() << endl; }
priority_queue的模擬實現(xiàn)
priority_queue的底層實際上就是堆結(jié)構(gòu),可以參考博主之前寫的有關堆的文章數(shù)據(jù)結(jié)構(gòu)之堆
namespace nzb { //比較方式(使內(nèi)部結(jié)構(gòu)為大堆) template<class T> class Less { public: bool operator()(const T& x, const T& y) { return x < y; } }; //比較方式(使內(nèi)部結(jié)構(gòu)為小堆) template<class T> class Greater { public: bool operator()(const T& x, const T& y) { return x > y; } }; template<class T, class Container = vector<T>, class Compare = Less<T>> class priority_queue { public: priority_queue() {} template<class InputIterator> priority_queue(InputIterator first, InputIterator last) { //將迭代器中的數(shù)據(jù)插入優(yōu)先級隊列中 while (first != last) { _con.push_back(*first); first++; } //從最后一個非葉子結(jié)點向上調(diào)整 for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--) { AdjustDown(i); } } //堆的向上調(diào)整 void AdjustUp(size_t child) { size_t parent = (child - 1) / 2;//找到父節(jié)點 while (child > 0) { if (_com(_con[parent], _con[child]))//判斷是否需要交換 { //交換父子結(jié)點 swap(_con[parent], _con[child]); //繼續(xù)向上調(diào)整 child = parent; parent = (child - 1) / 2; } else { break; } } } //向下調(diào)整 void AdjustDown(size_t parent) { size_t child = parent * 2 + 1;//算出左子節(jié)點的下標 while (child < _con.size()) { //找出子結(jié)點中符合比較方式的值 if (child + 1 < _con.size() && _com(_con[child], _con[child + 1])) { child++; } //通過所給比較方式確定是否需要交換結(jié)點位置 if (_com(_con[parent], _con[child])) { //交換父子結(jié)點 swap(_con[parent], _con[child]); //繼續(xù)向下調(diào)整 parent = child ; child = parent * 2 + 1; } else { break; } } } //插入數(shù)據(jù) void push(const T& x) { _con.push_back(x); AdjustUp(_con.size() - 1);//將最后一個元素向上調(diào)整 } //刪除數(shù)據(jù) void pop() { swap(_con[0], _con[_con.size() - 1]);//交換首尾數(shù)據(jù) _con.pop_back();//尾刪 AdjustDown(0);//首元素向下調(diào)整 } //訪問頭元素 const T& top() const { return _con[0]; } //獲取隊列中有效元素個數(shù) size_t size() { return _con.size(); } //判空 bool empty() { return _con.empty(); } private: Container _con;//底層容器 Compare _com;//比較方式 }; }
到此這篇關于C++中priority_queue的使用與模擬實現(xiàn)的文章就介紹到這了,更多相關C++ priority_queue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
va_list(),va_start(),va_arg(),va_end() 詳細解析
這些宏定義在stdarg.h中,所以用到可變參數(shù)的程序應該包含這個頭文件.下面我們寫一個簡單的可變參數(shù)的函數(shù),該函數(shù)至少有一個整數(shù)參數(shù),第二個參數(shù)也是整數(shù),是可選的.函數(shù)只是打印這兩個參數(shù)的值2013-09-09C語言中pthread_create函數(shù)實現(xiàn)向線程函數(shù)傳遞參數(shù)
本文主要介紹了C語言中pthread_create函數(shù)實現(xiàn)向線程函數(shù)傳遞參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05C++實現(xiàn)“隱藏實現(xiàn),開放接口”的方案
本文從一個實例講解了C++實現(xiàn)“隱藏實現(xiàn),開放接口”的方案,文章條理清新,內(nèi)容充實,需要的朋友可以參考下2015-07-07c++將引用或者是指針作為函數(shù)參數(shù)實現(xiàn)實參的運算
這篇文章主要介紹了c++將引用或者是指針作為函數(shù)參數(shù)實現(xiàn)實參的運算,需要的朋友可以參考下2014-05-05