【剑指offer-解题系列(64)】数据流中的中位数

来源:互联网 发布:遥远地球之歌 知乎 编辑:程序博客网 时间:2024/06/03 10:50

题目描述

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

分析

使用两个堆排数组,一个最大堆(前半段数据),一个最小堆(后半段数据)。
两个堆总共只有两种情况:
1、最大堆和最小堆数量相等(此时返回两个堆顶数目的相加平均)
2、最小堆数量多一个(返回最小堆顶元素)

如果新来的数字大于最小堆堆顶(属于后半段),那么塞入后半段数组
如果新来的属于前半段,塞入前半段数组

如果发现两边数目不均衡(最小堆-最大堆数目  超过1),则将进行最小堆顶元素给到最大堆,并且调整两个堆

代码实现

vector<int>min_half; // 最大堆
vector<int>max_half; // 最小堆
void Insert(int num)
{
    if(min_half.size()<=0){
        min_half.push_back(num);
        return;
    }
    if(max_half.size()<=0){
        max_half.push_back(num);
        if(max_half[0]<min_half[0])swap(max_half[0],min_half[0]);
        return;
    }
    if(min_half.size()==max_half.size()){
        if(num>min_half[0]){
            min_half.push_back( min(num,max_half[0]));
            max_half[0]=max(num,max_half[0]);
            
            HeapAdjustMax(min_half,0,min_half.size()-1);
            HeapAdjustMin(max_half,0,max_half.size()-1);
        }
        else{
            min_half.push_back(num);
            HeapAdjustMax(min_half,0,min_half.size()-1);
        }
    }
    else{
        if(num>min_half[0]){
            max_half.push_back(num);
            HeapAdjustMin(max_half,0,max_half.size()-1);
        }
        else{
            
            
            max_half.push_back( max(num,min_half[0]));
            min_half[0]=min(num,max_half[0]);
            
            HeapAdjustMax(min_half,0,min_half.size()-1);
            HeapAdjustMin(max_half,0,max_half.size()-1);
        }
    }
    
}




double GetMedian()

    if(min_half.size()==max_half.size()+1){
        return min_half[0];
    }
    else
        return 0.5*min_half[0]+0.5*max_half[0];
}


void HeapAdjustMax(vector<int>&a,int start,int end){
    if(start>=end)
        return ;
    for(int i =end;i>=start;i--){
        int left = 2*i+1;
        int right= 2*i+2;
        if(left<=end){
            if(right<=end){
                if(a[right]>a[left] && a[right]>a[i])
                    swap(a[i],a[right]); 
                else if(a[left]>a[i] && a[left]>a[right])
                    swap(a[i],a[left]);
            }
            else
                if(a[left]>a[i])
                    swap(a[i],a[left]);
        }
    }
}


void HeapAdjustMin(vector<int>&a,int start,int end){
    if(start>=end)
        return ;
    for(int i =end;i>=start;i--){
        int left = 2*i+1;
        int right= 2*i+2;
        if(left<=end){
            if(right<=end){ 
                if(a[right]<a[left] && a[right]<a[i])
                    swap(a[i],a[right]); 
                else if(a[left]<a[i] && a[left]<a[right])
                    swap(a[i],a[left]);
            }
            else
                if(a[left]<a[i])
                    swap(a[i],a[left]);
        }
    }
}
阅读全文
0 0
原创粉丝点击