写在前面
先了解一下priority_queue
而它的底层实际上就是用堆(Heap
)实现的
C++关于Priority_queue的实现
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
priority_queue<int> heap0; // 默认
priority_queue<int, vector<int>, less<int>> heap1; // 大顶堆
// less 值小的往叶子结点 所以根节点就是最大值
priority_queue<int, vector<int>, greater<int>> heap2; // 小顶堆
// greater 值大的往叶子结点,所以根节点就是最小值
vector<int> nums = {2,1,3,5,9,7};
for(int i = 0; i<nums.size();i++){
heap0.push(nums[i]);
heap1.push(nums[i]);
heap2.push(nums[i]);
}
while(!heap0.empty()){
int data = heap0.top();
cout << data << " ";
heap0.pop();
}
cout << endl;
while (!heap1.empty())
{
int data = heap1.top();
cout << data << " ";
heap1.pop();
}
cout << endl;
while (!heap2.empty())
{
int data = heap2.top();
cout << data << " ";
heap2.pop();
}
cout << endl;
system("pause");
return 0;
}
上面greater<int>
和less<int>
,就是一个仿函数,也叫做函数对象。
本题求解
class MedianFinder
{
public:
/** initialize your data structure here. */
// 容器的声明例如 vector<int> list<int> 是尖括号 不是圆括号!!!
priority_queue<int, vector<int>, less<int>> maxHeap; // 大顶堆 最外层是尖括号!
priority_queue<int, vector<int>, greater<int>> minHeap; // 大顶堆 最外层是尖括号!
int countn = 0; // 记录插入的数字数目
MedianFinder()
{
}
void addNum(int num)
{
// 先插入元素再调整大小
// 1. 插入元素
if (maxHeap.empty() || num <= maxHeap.top())
{
// cout << num << " 存入左边" << endl;
maxHeap.push(num);
}
else
{
// cout << num << " 存入右边" << endl;
minHeap.push(num);
}
// 2. 调整大小 每插入一个 都确保 左边个数-右边个数 >=1
// 左边比右边多2,左边转去右边
if (!maxHeap.empty() && (maxHeap.size() > minHeap.size() + 1))
{
// 非空才能取到top 否则报错。
// 使用 maxHeap.size() - minHeap.size() > 1 会报错
// 例如 1减2理论上应该得到-1,但是实际上得到一个很大的数
// 分析:.size()返回的size_type类型而不是int型,两个size_type运算得到的依旧是size)type;
// 而size_type是一个unsigned型的变量,所以负数就溢出了
minHeap.push(maxHeap.top());
maxHeap.pop();
}
// 右边比左边多1,右边转到左边
if (!minHeap.empty() && (minHeap.size() >= maxHeap.size() + 1))
{
// 非空才能取到top 否则报错
maxHeap.push(minHeap.top());
minHeap.pop();
}
countn++;
}
double findMedian()
{
if (countn % 2 == 1)
return 1.0 * maxHeap.top();
else
return 0.5 * (maxHeap.top() + minHeap.top());
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/