2.4.30动态中位数查找----优先队列

算法第四版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;
//     }
// };
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bug.Remove()

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值