双堆维护中位数

1,先把第一个数赋给mid
2,后来的数如果>=mid就插入到小顶堆<=mid就插入到大顶堆
3,每次插入新的值后都保证小顶堆的大小与大顶堆相等或大1
4,最后的中位数就是mid(n为奇数),或者mid和小顶堆的堆顶元素的平均

priority_queue<int,vector<int>,greater<int> >smallseq;
priority_queue<int,vector<int>,less<int> >bigseq;
int mid;
int a[100000];
void fun(int n)
{
    float midian;
    bool flag=true;//第一个数插入的标记
    for(int i=1;i<=n;i++){
        if(bigseq.empty()&&smallseq.empty()&&flag){
            mid=a[i];
            flag=false;
        }else{
            if(a[i]>=mid) smallseq.push(a[i]);
            else bigseq.push(a[i]);
            if(smallseq.size()==bigseq.size()+2){//维护两个堆的大小
                bigseq.push(mid);
                mid=smallseq.top();
                smallseq.pop();
            }else if(bigseq.size()==smallseq.size()+1){
                smallseq.push(mid);
                mid=bigseq.top();
                bigseq.pop();
            }
        }
    }
    if(smallseq.size()==bigseq.size())
        midian=mid;
    else
        midian=(mid+smallseq.top())/2.0;
    printf("%g\n",midian);
}
void init()
{
    while(!smallseq.empty()) smallseq.pop();
    while(!bigseq.empty()) bigseq.pop();
}

猜你喜欢

转载自blog.csdn.net/blue_kid/article/details/79165048