您的位置:首页 > 其它

中位数

2015-10-11 18:07 246 查看
问题描述

中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数或最中间两个数据的平均值(如果这组数的个数为奇数,则中位数为位于中间位置的那个数;如果这组数的个数为偶数,则中位数是位于中间位置的两个数的平均值).

给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)

输入

该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1 <= N <= 15000.

接着N行为N个数据的输入,N=0时结束输入

输出

输出中位数,每一组测试数据输出一行

输入示例

4
10
30
20
40
3
40
30
50
4
1
2
3
4
0


输出示例

25
40
2


提示

这是也一道经典的算法问题,在企业面试里出现概率很高,是“找到第K大的数”的变种。先排序再找中位数自然是很直接的做法,但排序本身很慢。我们只想找到第n/2大的数,对于其他数的顺序我们并不关心。那么怎么在不排序的前提下找到第n/2大的数呢?

源码

#include <iostream>
#include <vector>
using namespace std;

int main()
{
int numGroup = 0;
vector<int> numAve;
while(1)
{
int N = 0;
cin >> N;
if (N == 0)
{
break;
}
else
{
vector<int> sample(N);
for (int i = 0; i < N; i++)
{
cin >> sample[i];
}
if (N%2 != 0)
{
int k = N/2 +1;
for (int i = 0; i < k; i++)
{
for (int j = i; j < N; j++)
{
if (sample[j] > sample[i])
{
int temp = sample[j];
sample[j] = sample[i];
sample[i] = temp;
}
}
}
numAve.push_back(sample[k-1]);
//              cout << sample[k-1] << endl;
}
else
{
int k = N/2 +1;
for (int i = 0; i < k; i++)
{
for (int j = i; j < N; j++)
{
if (sample[j] > sample[i])
{
int temp = sample[j];
sample[j] = sample[i];
sample[i] = temp;
}
}
}
numAve.push_back((sample[k-2]+sample[k-1])/2);
//              cout << (sample[k-2]+sample[k-1])/2 << endl;
}
}
numGroup++;
}
for (int i = 0; i < numGroup; i++)
{
cout << numAve[i] << endl;
}
return 0;
}


————————————————-2016/6/4———————————————–

昨天师兄说起去面试的时候,他们让写个中值滤波的程序,想起找中位数这个问题。

网上搜了一下,有些是借用了快排的思想做,最快的可达到最坏复杂度O(n)。

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