分治算法之找出2n个数的中位数

1、 设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有n个已经排好序的数。试设计一个O(logn)时间的分治算法,找出X和Y的2n个数的中位数,并证明算法的时间复杂性为O(logn)

答:找出两个有序数组的中位数最简单暴力的方法是将两个数组合并成一个数组,然后找出中间那个数字。这种算法时间复杂度为O(n).

    用分治算法解决,求出两个数组的中位数,然后比较这两个中位数的大小。

(1).如果这两个中位数相等,那么合并后的中位数一定是这个数。

(2)如果前面数组的中位数小于后面数组的,那么第一个数组中位数前的元素和第二个数组中位数后面的元素肯定不是合并后数组的中位数

(3)同理,如果第一个数组中位数大于第二个中位数,那么第一个数组中位数后的元素和第二个数组中位数前面的元素肯定不是合并后的中位数。

(4)将两个数组分别再分成两部分递归寻找中位数,最后找出中位数。

    程序代码:

#include<iostream>

#include<vector>

usingstd::vector;

using namespacestd;

/* run thisprogram using the console pauser or add your own getch,system("pause") or input loop */

float mid(intm, int n,int arry[])//该函数是为了找出中位数

{

       int middle = (n+m+1)/2;

       float re;

       if((n-m)%2==0)

         re = arry[middle]/1.0;  //如果数组的个数为奇数,直接取中间值

       else

         re = (arry[middle-1] + arry[middle])/2.0;//偶数则取中间两个数的平均数

       return re;

}

floatfindmid(int arry1[],int arry2[],int b1,int b2,int l1,int l2)

{

       int mid1 = (b1 + l1 + 1)/2;//中间位置

       int mid2 = (b2 + l2 + 1)/2;

       float mm1,mm2;

       mm1 = mid(b1,l1,arry1);//找出数组的中位数

       mm2 = mid(b2,l2,arry2);

       if(l1==b1 && l2==b2)

          return (mm1 + mm2)/2.0;//如果两个数组都只剩一个元素,则取两个数组中位数的平均值

       if(mm1 == mm2)

          return mm1;//中位数相等直接返回该中位数

       else if(mm1 < mm2) //第一个数组中位数小于第二个中位数,则舍掉第一个中位数前的数和第二个中位数后的数

       {

       if((l2-b2)%2!=0)

         returnfindmid(arry1,arry2,mid1,b2,l1,mid2-1);

       else

          return findmid(arry1,arry2,mid1,b2,l1,mid2);

       }

       else //第一个数组中位数大于第二个中位数,则舍掉第一个中位数后的数和第二个中位数前的数

       {

       if((l1-b1)%2!=0)

          return findmid(arry1,arry2,b1,mid2,mid1-1,l2);

       else

          return findmid(arry1,arry2,b1,mid2,mid1,l2);

       }

        

}

int main(intargc, char** argv) {

       int arry1[5]={1,5,6,8,9}, arry2[5]={1,2,6,7,10},i;

       cout<<"第一个有序数组:";

       for(i=0;i<5;i++)

         cout<<arry1[i]<<" ";

       cout<<endl<<"第二个有序数组:";

       for(i=0;i<5;i++)

         cout<<arry2[i]<<" ";

         cout<<endl<<"两个数组的中位数为:";

       cout<<findmid(arry1,arry2,0,0,4,4)<<endl;

}

运行结果:

   

时间复杂度分析:

 由于每次都是将数组分成两部分寻找中位数,从n,n/2,n/4,n/8……一直到1,所以时间复杂度为O(log2n).

 

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值