生活随笔
收集整理的這篇文章主要介紹了
详解优先级队列priority_queue(应用+模拟实现)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
優先級隊列的概念
優先隊列是一種容器適配器,根據嚴格的弱排序標準,它的第一個元素總是它所包含的元素中最大的此上下文類似于堆,在堆中可以隨時插入元素,并且只能檢索最大堆元素(優先隊列中位于頂部的元 素)。優先隊列被實現為容器適配器,容器適配器即將特定容器類封裝作為其底層容器類,queue提供一組特 定的成員函數來訪問其元素。元素從特定容器的“尾部”彈出,其稱為優先隊列的頂部。底層容器可以是任何標準容器類模板,也可以是其他特定設計的容器類。容器應該可以通過隨機訪問迭 代器訪問,并支持以下操作:
5. . 標準容器類vector和deque滿足這些需求。默認情況下,如果沒有為特定的priority_queue類實例化指 定容器類,則使用vector。
6. 需要支持隨機訪問迭代器,以便始終在內部保持堆結構。容器適配器通過在需要時自動調用算法函數 make_heap、push_heap和pop_heap來自動完成此操作。
priority_queue應用
優先級隊列默認使用vector作為其底層存儲數據的容器,在vector上又使用了堆算法將vector中元素構造成 堆的結構,因此priority_queue就是堆,所有需要用到堆的位置,都可以考慮使用priority_queue。注意: 默認情況下priority_queue是大堆
優先級隊列默認情況下是大堆
int main()
{priority_queue
<int>q1
; q1
.push(4);q1
.push(1);q1
.push(2);q1
.push(3);q1
.push(5);cout
<< q1
.size() << endl
;cout
<< q1
.top() << endl
;vector
<int>v
{ 3, 8, 2, 6, 0, 1, 9, 5, 7, 4 };priority_queue
<int>q2(v
.begin(),v
.end()); cout
<< q2
.size() << endl
;cout
<< q2
.top() << endl
;q2
.pop();cout
<< q2
.top() << endl
;system("pause");return 0;
}
2. 如何創建小堆
第一個參數代表優先級隊列里元素的類型,第二個參數代表優先級隊列在底層的時候,把元素放到vector里面,在放之前要先對優先級隊列里元素進行比較,怎么比較,就是第三個參數,優先級中元素的比較規則,默認為less,按照小于的方式進行比較得到的是大堆,所以我們如果要建小堆,就用大于的方式進行比較
vector
<int>v
{ 3, 8, 2, 6, 0, 1, 9, 5, 7, 4 };
priority_queue
<int,vector
<int>,greater
<int>>q2(v
.begin(),v
.end());
cout
<< q2
.size() << endl
;
cout
<< q2
.top() << endl
;
3. 如果在priority_queue中放自定義類型的數據,用戶需要在自定義類型中提供> 或者< 的重載。
class Date
{
public:Date(int year
, int month
, int day
):_year(year
), _month(month
), _day(day
){}bool operator<(const Date
& d
)const {return _day
< d
._day
;}private:int _year
;int _month
;int _day
;
};
priority_queue
<Date
>q
;
Date
d1(2019, 10, 18);
Date
d2(2019, 10, 17);
Date
d3(2019, 10, 16);
q
.push(d1
);
q
.push(d2
);
q
.push(d3
);
有些情況下,用戶可能需要提供比較器
指針:雖然可以直接比較,但是按結果地址給出大小堆,如果想要讓其按照指針所指向空間元素給出大小堆,必須改變比較規則
通過仿函數的方式傳比較規則
class Compare
{
public:bool operator()(Date
* pLeft
, Date
* pRight
){if (pLeft
->_day
< pRight
->_day
)return true;return false;}
};
priority_queue
<Date
*,vector
<Date
*>,Compare
>q2
;
q2
.push(&d3
);
q2
.push(&d1
);
q2
.push(&d2
);
在具體問題中的應用
優先級隊列最主要的應用就是解決TopK問題
可以先排降序,然后數組中第k個元素的下標就是K-1
class Solution {
public:int findKthLargest(vector
<int>& nums
, int k
) {sort(nums
.begin(),nums
.end(),greater
<int>());return nums
[k
-1];}
};
priority_queue
<int>q(nums
.begin(),nums
.end());
for(size_t i
=0 ;i
< k
-1; ++i
){q
.pop();}
return q
.top();
由于篇幅不易過長,所以接下來兩個知識點,另外寫兩篇體現,以下是鏈接
容器適配器
詳解容器適配器
模擬實現
模擬實現優先級隊列
總結
以上是生活随笔為你收集整理的详解优先级队列priority_queue(应用+模拟实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。