C++ 查找中位数

  • Post author:
  • Post category:其他

查找C++无序数列中位数

1.将无序数列转化为有序数列,然后直接通过索引找到中位数
2.已知中位数 要求左边小于(大于)中位数,右边大于(小于)中位数,且左边数列大小等于右边数列大小 。 而对左边数列或者右边数列数值的排列顺序无要求。
所以,我们可以采用优先队列进行解决。

代码实现

#include<iostream>
#include<queue>//优先队列
#include<vector>
#include<assert.h>
#include<list>

//利用优先队列实现,使得堆顶左边都比堆顶大,其余未入队列的数据全都比堆顶小,队列的大小应该为一半。

using namespace std;

template<class T>
T findMidle(const T *arr,int size)
{
    assert(arr);
    int len=0;
    //优先队列
    priority_queue<int,vector<int>,greater<int> > q;//从大到小

    if(size&1)//奇数
    {
        len=(size+1)/2;

        //将局部数据放入队列,pop为局部最小
        for(int i=0;i<len;++i)
        {
            q.push(arr[i]);
        }

        //大于堆顶的push进入队列,使得堆顶的左边比堆顶大,右边比堆顶小,此时堆顶为中位数
        for(int i=len;i<size;++i)
        {
            if(q.top()<arr[i])
            {
                q.pop();
                q.push(arr[i]);
            }
        }

        return q.top();

    }
    else//偶数
    {
        len=size/2;
        //优先队列
        //priority_queue<int,vector<int>,greater<int>()> q;//从大到小

        //将局部数据放入队列,pop为局部最小
        for(int i=0;i<len;++i)
        {
            q.push(arr[i]);
        }

        //大于堆顶的push进入队列,使得堆顶的左边比堆顶大,右边比堆顶小,此时堆顶为中位数

        int flag=0;//存储最后一次pop出来的数据
        for(int i=len;i<size;++i)
        {
            if(q.top()<arr[i])
            {
                flag=q.top();
                q.pop();
                q.push(arr[i]);
            }
        }

        return (q.top()+flag)/2;
    }
    
}

void test01()
{
    //准备数据
    int arr[]={10,20,12,16,15,4,8,10};//偶数重复,  4,8,10,10,12,15,16,20 中位数:11
    
    //int arr1[]={10,20,12,16,15,4,10};//奇数重复, 中位数:12

    int len=sizeof(arr)/sizeof(int);

    int ret=findMidle<int>(arr,len);

    cout<<"the middle is : "<<ret<<endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}

版权声明:本文为weixin_44444450原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。