👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨
目录
一、priority_queue的介绍
- 优先级队列顾名思义就是:按优先级出队列
priority_queue
是一个 容器适配器,默认使用vector
作为其底适配器,因此不支持随机访问。priority_queue
底层是 堆 ,默认情况下是大堆。- 头文件
#include <queue>
二、为什么priority_queue不使用deque作为默认适配器
首先优先级队列priority_queue
的适配器也可以用deque
,但是没有必要。
我们在上篇博客总结了deque
的缺点:
因此,可以得出priority_queue
不选择deque
作为默认适配器如下:
- 优先级队列的底层是一个堆,则需要频繁访问来保持大堆或小堆性质。(后面模拟实现会大量使用
[]
) deque
内部结构更为复杂(使用分段数组),在某些情况下可能会导致额外的开销。
三、priority_queue的常见操作
【代码演示】
- 小堆(在下面仿函数会详细介绍)
四、LeetCode 215. 数组中的第K个最大元素
class Solution {
public:
// 思路:使用大堆,然后弹k - 1次,堆顶即是k个最大元素
int findKthLargest(vector<int>& nums, int k)
{
// 默认是大堆
priority_queue<int> pq(nums.begin(), nums.end());
while (--k)
{
pq.pop();
}
return pq.top();
}
};
五、模拟实现priority_queue
5.1 迭代区间构造
- 参考博客:点击跳转
5.2 删除堆顶元素pop
5.3 插入push
5.4 获取堆顶元素top
5.5 判断是否为空empty
5.6 获取个数大小size
六、仿函数
简单来说:一个类中重载括号()
,并且这个类实例化后的对象可以像函数一样使用,实现了类似函数的行为。本质上是替代C语言里的函数指针。
例如,定义一个加法仿函数可以这样实现:
template<class T>
struct Add
{
int operator()(const T& a, const T& b) const
{
return a + b;
}
};
int main()
{
// 实例化
Add add;
int result = add(3, 5); // 调用仿函数
cout << "add(3, 5) = " << result << endl;
return 0;
}
在上面的例子中,Add
是一个仿函数,它重载了函数调用运算符 operator()
,使得add
对象可以像函数一样被调用。通过add(3, 5)
,我们可以得到结果8
- 在C++ 中,仿函数是一种灵活且强大的编程工具,常常用于算法和标准库中的函数对象。
就比如说sort
函数,默认排的是升序
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[] = { 5,1,4,2,0,3 };
int arrSize = sizeof(arr) / sizeof(arr[0]);
// less<int> 默认可以不写
sort(arr, arr + arrSize, less<int>());
for (int i = 0; i < arrSize; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}
【输出结果】
less
是库里提供的,其作用就是用于小于不等式比较的函数对象类
那么如果想排降序,可以将less
替换成greater
,这也是库里提供的,其作用是用于大于不等式比较的函数对象类
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[] = { 5,1,4,2,0,3 };
int arrSize = sizeof(arr) / sizeof(arr[0]);
// less<int> 默认可以不写
sort(arr, arr + arrSize, greater<int>());
for (int i = 0; i < arrSize; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}
【输出结果】
注意:如果在priority_queue
中放自定义类型的数据,用户需要在自定义类型中提供>
或者<
的重载。
七、实现priority_queue的仿函数(源码)
以上我们实现的是的优先级队列是大堆性质(默认),我们可以通过增加模板参数来实现大堆小堆秒切换。
八、源码
Gitee
仓库链接:点击跳转