您的位置:首页 > Web前端

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

2017-06-15 09:58 369 查看


题目描述

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


分析

使用两个堆排数组,一个最大堆(前半段数据),一个最小堆(后半段数据)。

两个堆总共只有两种情况:

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]);

        }

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: