【数组】数据流中的中位数

数据流中的中位数

题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

题目要求实时在插入的过程中得到当前数据流的中卫数,这里要利用到顶堆的概念:
顶堆结构实际上为二叉树的结构,这里当作数组看待比较容易理解,并且是一个二叉排序树,排序的规则为:
大顶堆–根节点值定大于子节点,转换为数组可理解为0号位置元素最大,且降序排列;
小顶堆–根节点值定小于子节点,转换为数组可理解为0号位置元素最小,且升序排列;

这道题的思路就是在插入过程中不断更新顶堆的存储内容,在取中位数时,直接取两顶堆头部元素平均值即可
需要比较细心的考虑很多种情况

priority_queue<int, vector<int>, less<int>> big;
priority_queue<int, vector<int>, greater<int>> small;
void Insert(int num)
{
    //每个数先放小顶堆中,考虑若此时大小顶堆size相同,一个很小的数放入小顶堆中会导致中位数计算错误
    //对于这种情况如何避免,始终让大顶堆size大于等于小顶堆,返回大顶堆top
    if(big.empty() || num < big.top()) big.push(num);//保证大顶堆头部为中位数
    else small.push(num);
    if(big.size() - small.size() == 2) {
        small.push(big.top());
        big.pop();
    }
    if(small.size() - big.size() == 1){
        big.push(small.top());
        small.pop();
    }
}

double GetMedian()
{ 
    return small.size()==big.size()? (small.top()+big.top())/2.0 : big.top();
}

猜你喜欢

转载自blog.csdn.net/qq_34606546/article/details/86726464
今日推荐