二叉堆,堆排序,STL优先队列的底层实现,剑指offer数据流中的中位数

一.

  • 下图是从数组为0下标开始计算的。
    二叉堆,堆排序,STL优先队列的底层实现,剑指offer数据流中的中位数_第1张图片

  • 下图是从数组为1下标开始计算的。引自《STL源码剖析》 p173
    二叉堆,堆排序,STL优先队列的底层实现,剑指offer数据流中的中位数_第2张图片


  • 堆排序

  • 64.数据流中的中位数。《剑指offer》 p286

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

class Solution {
public:
    void Insert(int num)
    {
        if((max.size()+min.size()) % 2 == 0)   //数据总数目是偶数,将新的数据放入到最小堆中
        {
            if(!max.empty() && num < max[0])   //如果新插入的数据比最大堆的最大值要小,那么就将新数据插入到最大堆中,并将最大堆的最大值弹出,放到最小堆中
            {
                max.push_back(num);
                push_heap(max.begin(),max.end(),less<int>());

                pop_heap(max.begin(),max.end(),less<int>());  //弹出最大堆的最大值
                num = max.back();
                max.pop_back();
            }

            min.push_back(num);
            push_heap(min.begin(),min.end(),greater<int>()); //组建最小堆

        }
        else   //数据总数目是奇数,将新数据放入到最大堆中
        {
            if(!min.empty()&&num > min[0])  //新插入的数据比最小堆的最小值还要大,那么就将新插入的数据放入最小堆中,并将最小堆的最小值弹出,放入最大堆中
            {
                min.push_back(num);
                push_heap(min.begin(),min.end(),greater<int>());

                pop_heap(min.begin(),min.end(),greater<int>());  //弹出最小堆最小值
                num = min.back();
                min.pop_back();
            }    

            max.push_back(num);
            push_heap(max.begin(),max.end(),less<int>());

        }
    }

    double GetMedian()
    { 
        int size = max.size()+min.size();
        if(size == 0)
            return 0;
        double res = 0;
        if(size % 2 == 1)
        {
            /*
           if(min.empty())
                res = max[0];

            if(max.empty())
                res = min[0];*/            
            res = min[0];  //当只有一个元素,不需要判断是最大堆还是最小堆,因为一个数是奇数,一定是放到最小堆中。
        }
        else
           res = (max[0]+min[0])/2;

        return res;
    }

    vector max; //最大堆  //***涉及到浮点运算,原始数据存储用double
    vector min; //最小堆
};

你可能感兴趣的:(C++语言学习)