您的位置:首页 > 其它

两个等长有序数组求中位数

2012-12-27 23:44 260 查看
在网上看了很多两个等长有序数组求中位数的文章,但我都觉得有点儿问题。等下会说我觉得问题在哪里。

先说下中位数定义:当数组元素个数为奇数个的时候,中位数就是中间的数字,比如数组[1,2,3,4,5],那么3就是中位数。如果数组元素个数为偶数个的时候,那么中间两个元素的平均值就是中位数的值,比如数组[1,2,4,5],那么中位数就是(2+4)/2=3.

定义清楚了下面就来说下两个等长数组求中位数的问题,为了简化问题,直接假设两个数组都按从小到大顺序排列好了。两个等长数组,那么总的元素个数肯定为偶数,那么结果就肯定是某两个数字的平均值。

求解方法基本都一样,就是用二分搜索的思路来做。假设有两个数组A,B,首先用两个指针a,b分别指向A,B中间的数字,然后比较这两个数字,假设a指向数字大于b的数字,那么结果肯定不在a指向数字的右边和b指向数字的左边。然后分别向左向右移动a,b两个指针,再次进行比较。就是二分搜索的思路。

然后说问题,在网上看了好多博客,求得的结果都是指针移动的最后结果是A中某一元素和B中某一元素一起作为结果。但我认为这是不对的,因为最终结果的两个数字完全可以在同一个数组中,假设有两个数组

A:1 2 7 9 10
B:3 4 5 6 8
合并后中位数应该是5 和 6,两个数都在数组B中,并不是A、B各一个数。

网上很多人写的迭代结束条件都是找到了a=b或者最后子数组长度都为1,我觉得结束条件应该是找到a=b或者数组长度为2。

可能对于这个问题有点儿钻牛角尖了,思路大家基本都差不多,只是我在迭代的结束条件上和大家看法不太一样,也许我考虑的有问题,希望各位批评指正。

以下是实现代码:

#include <stdio.h>

void findMedian(int first[],int second[],int length);

int result[4];//因为是迭代为2的时候结束,所以会有4个数字对于四个数字应该还排下序,然后取中间两个,这里直接打印输出

int main(void){
int first[]={1,2,3,6,11};
int second[]={4,7,8,10,12};
findMedian(first,second,5);//随便写的两个数组例子
printf("%d  %d  %d  %d\n",result[0],result[1],result[2],result[3]);//

}

void findMedian(int first[],int second[],int length){
if(length<=2){
result[0]=first[0];
result[1]=first[1];
result[2]=second[0];
result[3]=second[1];
}
int low1=0,low2=0,high1=length-1,high2=length-1;
int current1,current2,k1,k2;
while(length>2){
current1=(low1+high1)/2;
current2=(low2+high2)/2;
if(first[current1]==second[current2]){
printf("The median is %d\n",first[current1]);

 //因为主函数中有输出,所以这里就赋了下值

result[0]=first[current1];

result[1]=first[current1];
result[2]=first[current1];
result[3]=first[current1];

return;
}
else if(first[current1]>second[current2]){

//k1 k2表示当前指针和边界的距离,因为存在奇偶问题,所以k1和k2不一定相同,指针移动时候要移动二者中较小的距离
k1=high1-current1;
k2=current2-low2;
if(k1==k2){
high1=current1;
low2=current2;
length-=k1;
}
else if(k1>k2){
high1=current1+1;
low2=current2;
length-=k2;
}
else{
high1=current1;
low2=current2-1;
length-=k1;
}
}
else{
k1=current1-low1;
k2=high2-current2;
if(k1==k2){
high2=current2;
low1=current1;
length-=k1;
}
else if(k1>k2){
low1=current1-1;
high2=current2;
length-=k2;
}
else{
high2=current2+1;
low1=current1;
length-=k1;
}
}
}

result[0]=first[low1];
result[1]=first[high1];
result[2]=second[low2];
result[3]=second[high2];

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