算法第四版2.4.30题目,插入和删除O(lgn),查找O(1)
//动态查找中位数
//常数时间内找到中位数,O(logn)时间内插入和删除中位数
//解题思路
//1、创建两个堆,一个大顶堆,一个小顶堆
//2、大顶堆的堆顶放中位数,
//3、保证插入的元素均匀分布在两个堆中
/*
注:
1.大顶堆的元素一定小于等于小顶堆的元素
2.要弹出堆的元素数量一定不小于插入堆的元素数量
3.如果是大堆插入,小堆弹出,则中位数为中间(正好是奇数时)或者N/2+1;
4.如果是小堆插入,大堆弹出,则中位数为中间(正好是奇数时)或者N/2-1;
*/
#include <vector>
#include <queue>
using std::greater;
using std::less;
using std::priority_queue;
using std::queue;
using std::vector;
class Mid_Priority_Queue
{
private:
priority_queue<int, vector<int>, less<int>> MaxQue; //大顶堆
priority_queue<int, vector<int>, greater<int>> MinQue; //小顶堆
int nLen;
public:
Mid_Priority_Queue()
{
nLen = 0;
}
public:
void Push(int element)
{
//向大顶堆添加元素
MaxQue.push(element);
//如果小顶堆里的元素数比大顶堆里的元素数少,则将大顶堆的堆顶元素移到小顶堆
if (MaxQue.size() > MinQue.size())
{
MinQue.push(MaxQue.top());
MaxQue.pop();
}
if (MaxQue.size() == MinQue.size()) //如果两个堆里的元素相等
{
//保证大顶堆里的元素都小于小顶堆里的元素
if (MaxQue.top() > MinQue.top())
{
MinQue.push(MaxQue.top());
MaxQue.pop();
MaxQue.push(MinQue.top());
MinQue.pop();
}
}
++nLen;
}
int Search()
{
return MinQue.top();
}
int top()
{
if (MinQue.size() == 0)
return -1;
return MinQue.top();
}
int Pop()
{
if (!nLen)
return -1;
//从大顶堆插入元素,则就从小顶堆弹出元素。
int value = top();
MinQue.pop();
//删除元素后如果小顶堆的元素小于大顶堆的元素,则将大顶堆的堆顶元素移入小顶堆,保证弹出元素的堆不小于插入元素的堆
if (MaxQue.size() > MinQue.size())
{
MinQue.push(MaxQue.top());
MaxQue.pop();
}
//同理,()
--nLen;
return value;
}
int Size()
{
return nLen;
}
};
// class Mid_Priority_Queue
// {
// private:
// priority_queue<int, vector<int>, less<int>> MaxQue; //大顶堆
// priority_queue<int, vector<int>, greater<int>> MinQue; //小顶堆
// int nLen;
// public:
// Mid_Priority_Queue()
// {
// nLen = 0;
// }
// public:
// void Push(int element)
// {
// //向小顶堆添加元素
// MinQue.push(element);
// //如果小顶堆里的元素数比大顶堆里的元素数多,则将小顶堆的堆顶元素移到大顶堆
// if (MinQue.size() > MaxQue.size())
// {
// MaxQue.push(MinQue.top());
// MinQue.pop();
// }
// if (MinQue.size() == MaxQue.size()) //如果大顶堆和小顶堆里的元素数相同
// {
// //如果小顶堆的堆顶元素小于大顶堆的堆顶元素,则交换
// if (MinQue.top() < MaxQue.top())
// {
// MinQue.push(MaxQue.top());
// MaxQue.pop();
// MaxQue.push(MinQue.top());
// MinQue.pop();
// }
// }
// ++nLen;
// }
// int top()
// {
// return MaxQue.top();
// }
// int Pop()
// {
// if (!nLen)
// return -1;
// //如果从小顶堆插入元素,则从大顶堆弹出元素
// int value = top();
// MaxQue.pop();
// //删除元素后如果大顶堆的元素小于小顶堆的元素,则将小顶堆的堆顶元素移入大顶堆
// if (MaxQue.size() < MinQue.size())
// {
// MaxQue.push(MinQue.top());
// MinQue.pop();
// }
// --nLen;
// return value;
// }
// int Size()
// {
// return nLen;
// }
// };