C语言:求两个有序数组的中位数

写在前面 本题值得回看 受https://blog.csdn.net/hk2291976/article/details/51107778启发
尤其是链接中的 割 的思想 求中位数最大的问题是数组个数的奇数偶数问题
length/2 +1(length为奇数)
mid={
length/2+1的值+length/2的值 除以2 (length为偶数)
割的思想:
例子
有数组 1,2,3,4 其中含有4个元素 现在填满这个数组的空余 #1#2#3#4# 此时数组中元素个数为9 割在第(9/2=4)个字符上 有趣的是 4/2=2 (4-1)/2=1 分别对应1,2,3,4中的2和3(C语言下标从0开始)
有数组 1,2,3,4,5 其中含有5个元素 现在填满这个数组的空余 #1#2#3#4#5# 此时数组中元素个数为11 割在第(11/2=5)个字符上 有趣的是 5/2=2 (5-1)/2=2 分别对应1,2,3,4,5中的3和3(C语言下标从0开始)
通过上面的例子 我们发现通过变换可以将 奇数个数组与偶数个数组都转化为奇数个数组,也发现求其中位数就是使用割在数组一般的字符上的方法,而它的值除二以及它的值减一除二分别对应元素组的坐标 将坐标位置的数值相加除二得到中位数的值
#include<stdio.h>
int flag=0;
void main(){
int a[4]={19,19,19,19};//数组a
int b[5]={2,6,9,13,15};//数组b
int al=4;//数组a的长度
int bl=5;//数组b的长度
int low=0;//形如二分查找的low
int high=2al;//形如二分查找的high,这里经过虚拟填充字符变换所以乘二
int l1,l2,r1,r2,t1,t2;
/这里a数组的长度一定要小于b数组的长度,因为提高效率,处理两种极端情况即可/
while(low<=high){
int c1=(low+high)/2;//形如二分查找里的mid
int c2=al+bl-c1;//设第k位为中位数那么第二个数组在 中位的初始位置是k-c1
if(c1= =0){//处理第一种极端情况,此时c1=0意味着数组a中所有的元素都大于b,已知数组a的长度小于数组b,那么中位数一定在数组b中
t1=b[(al+bl)/2];//我们把两个数组拼接在一起此时长度为
2al+2b1+1而不是2al+2bl+3具体原因可以查找割操作字符填充的形式。向下取整此时割的位置在al+bl处套用公式 返回值
t2=b[(al+bl-1)/2];
printf("%d",(t1+t2)/2);
flag=1;
}
if(c1= =2
al){
t1=b[(al+bl+1-2al-1-1)/2];
t2=b[(al+bl+1-2
al-1)/2];
printf("%d",(t1+t2)/2);
flag=1;
}
l1=a[(c1-1)/2];
r1=a[(c1)/2];
l2=b[(c2-1)/2];
r2=b[(c2)/2];
if(l1>r2){//已知有序数组所以 l1<r1 l2<r2 若l1<r2且l2<r1 那么整个数组的左边全部小于右边,如果不是那么类似二分查找,分别向左或者向右移动指针直至满足条件
high=c1-1;
}
else if(l2>r1){
low=c1+1;
}
else{
break;
}
}
if(flag==0){//l1<r2且l2<r1 那么开始确定中位数的具体值 显然两个l中最大的两个r中最小的更接近整体割的位置
int min=l1>l2?l1:l2;
int max=r1>r2?r2:l1;
printf("%d",(min+max)/2);
}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值