求一个无序数组的中位数

来源:互联网 发布:权力的游戏收视率数据 编辑:程序博客网 时间:2024/05/22 01:31

求一个无序数组的中位数。

如:{2,5,4,9,3,6,8,7,1}的中位数为5,{2,5,4,9,3,6,8,7,1,0}的中位数为4和5。
要求:不能使用排序,时间复杂度尽可低。

实现思路:

解法一:快排思想

【背景知识】
1.快速排序可以实现将数据划分为 三部分 : 左边小于基准值 基准值 右边大于基准值位置

2.每次划分都可以将基准值的最终确定, 那这样的话,我们找中位数就很方便了。
如果划分返回的区间

  1. 小于mid 去 右区间进行下一步查找
  2. 大于mid 去 左区间进行下一步查找
  3. ==mid 返回

代码实现:

int PartionMid(int array[], int left ,int right){    int key = array[right];    int begin = left;    int end = right;    while (begin < end)    {        while (begin < end&&array[begin] <=key)   //注意是<=         {            begin++;        }        while (begin < end&&array[end] >=key)        {            end--;        }        if (begin < end)        {            swap(array[begin],array[end]);        }    }    swap(array[begin], array[right]);    return begin;}//实现思路: 如果下标<mid去左区间找   ,如果下标>mid  去右区间找int FindMid(int array[], int size){    int mid = (size-1)/ 2;    int left = 0;    int right = size - 1;    int index = 0;    index = PartionMid(array, left, right);    while (index != mid)    {        if (index < mid)  //去右区间找        {            index = PartionMid(array, index+1, right);        }        else if (index>mid)//去左区间找        {            index = PartionMid(array, left, index-1);        }    }    return array[mid];}

解法二: TopK问题

求中间大元素:建小堆,每次和当前堆最小值进行比较,
1.如果小于堆顶(当前堆最小值),说明不是 前K个数据,直接过滤掉
2.如果大于堆顶(当前堆最小值),说明有可能是 前K个数据
替换掉堆顶,再次对当前堆顶进行调整,满足最小堆性质

另外:优先级队列的底层也是通过建堆来实现的。默认是建大堆,此时就要编写一个使其建小堆的仿函数了,其实也就是相当于修改了它的优先级。

代码实现:

//优先级队列实现 :天然的堆int GetMidByQue(int arr[], int size){    int mid = (size) / 2+1;      struct Com    {        bool operator ()(int num1, int num2)        {            return num1 > num2;        }    };    priority_queue<int, vector<int>,Com> q;    for (int i = 0; i < mid; i++)    {        q.push(arr[i]);    }    for (int i = mid; i < size; i++)    {        if (arr[i]>q.top())  //替换掉元素        {            q.pop();            q.push(arr[i]);        }    }    //返回堆顶元素即可    if (!q.empty())    {        return q.top();    }    else    {        return -111111;    }}
原创粉丝点击