问题描述
设X[ 0 : n - 1]和Y[ 0 : n – 1 ]为两个数组,每个数组中含有n个已排好序的数。找出X和Y的2n个数的中位数。
编程任务
利用分治策略试设计一个O (log n)时间的算法求出这2n个数的中位数。
数据输入
文件的第1行中有1个正整数n(n<=200),表示每个数组有n个数。接下来的两行分别是X,Y数组的元素。
结果输出
程序运行结束时,输出计算出的中位数。
输入示例
3
5 15 18
3 14 21
输出示例
14.5
方法一:归并排序
#include<iostream>
#include<vector>
#include<cmath>
#include <algorithm>
using namespace std;
//归并排序
void merge(vector<int>&c, int low,int mid, int hight)
{
vector<int>temp(hight - low + 1);
int i = low, j = mid + 1, k = 0;
while (i <= mid && j <= hight)
{
if (c[i] <= c[j])
{
temp[k++] = c[i++];
}
else
{
temp[k++] = c[j++];
}
}
while (i <= mid)
{
temp[k++] = c[i++];
}
while (j <= hight)
{
temp[k++] = c[j++];
}
k = 0;
for (int i = low; i <= hight; i++)
{
c[i] = temp[k++];
}
temp.clear();
}
void mergesort(vector<int>&c, int low, int hight)
{
if (low < hight)
{
int mid = (low + hight) / 2;
mergesort(c, low, mid);
mergesort(c, mid + 1, hight);
merge(c, low, mid, hight); //进行合并操作
}
}
int main()
{
int n;
cin >> n;
vector<int> a(n);
vector<int> b(n);
vector<int> c(2*n);
for (int i = 0; i < n; i++) {
cin >> a[i];
c[i] = a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
c[i + n] = b[i];
}
mergesort(c, 0, 2*n - 1);
cout << (c[n-1] + c[n ]) / 2.0;
return 0;
}
方法二:直接判断是否会存在中位数在一个数组中
如
3
1 2 3
-1 4 5 情况
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
// 计算中位数
double zhong(vector<int> a)
{
int len = a.size();
if (len % 2 == 0) {
return (a[len / 2 - 1] + a[len / 2]) / 2.0;
}
else {
return a[len / 2];
}
}
// 递归计算中位数
double zhongwei(vector<int> a, vector<int> b, int n)
{
if (n == 1)
{
return (a[0] + b[0]) / 2.0;
}
//防止中位数在一个数组中
if (n % 2 == 0)
{
if (a[n / 2 - 1] > b[n / 2 - 1] && a[n / 2] < b[n / 2 ])
{
return (a[n / 2 - 1] + a[n / 2]) / 2.0;
}
}
if (n % 2 == 0)
{
if (b[n / 2 - 1] > a[n / 2 - 1] && b[n / 2] < a[n / 2 ])
{
return (b[n / 2 - 1] + b[n / 2]) / 2.0;
}
}
//防止逆序
if (a[1] < a[0])
{
reverse(a.begin(), a.end());
}
if (b[1] < b[0])
{
reverse(b.begin(), b.end());
}
double x = zhong(a);
double y = zhong(b);
double f = 0;
if (x == y)
{
return x;
}
if (x > y) {
vector<int> c(a.begin(), a.begin() + (int)ceil((float)n / 2));
vector<int> d(b.begin() + n / 2, b.end()); // 修正切片范围
n = (int)ceil((float)n / 2);
f = zhongwei(c, d, n);
}
if (x < y) {
vector<int> c(a.begin() + n / 2, a.end()); // 修正切片范围
vector<int> d(b.begin(), b.begin() + (int)ceil((float)n / 2));
n = (int)ceil((float)n / 2);
f = zhongwei(c, d, n);
}
return f;
}
int main() {
int n;
cin >> n;
vector<int> a(n);
vector<int> b(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
cin >> b[i];
}
cout << zhongwei(a, b, n);
return 0;
}