求两个有序数组的中位数

来源:互联网 发布:淘宝店怎么做百度推广 编辑:程序博客网 时间:2024/04/30 20:11

     设两个有序数组X[1...n],Y[1...n],每个包含n个有序元素,设计一个O(logn)的算法来找出X和Y中2n个数的中位数。

    分析可知,本问题不难使用一个O(n)的算法解决。题目要求的算法时间是O(logn),由于两个数组是有序的,我们考虑用二分的办法。以下在这里求的中位数是上中位数,也就是2n个数中的第n+1大的数取X与Y的中位数进行大小比较,若X[n/2]==Y[n/2],那么X[n/2]就是原数组中位数。若X[n/2]>Y[n/2],说明中位数在X[1...n/2]和Y[n/2...n]之间。若X[n/2]<Y[n/2]说明中位数在X[n/2...n]和Y[1...n/2]之间。在具体处理时候,要注意n的奇偶性,如下:

  当n为奇数时,如n=5:

      X:1 ,5 ,9 ,10 ,15

      Y:0 ,2 ,6 , 9 , 16

发现9>6于是中位数必定存在X:1,5,9和Y:6,9,10之间,注意此时9可能作为上中位数,从而不可去掉

   当n为偶数时,如n=6:

      X:1 ,5 ,9 ,10 ,15  20

      Y:0 ,2 ,6 , 9 , 16  17

先比较10>9,此时n为偶数,10不可能为中位数,但是9有可能,于是中位数在X:1,5,9和Y:9,16,17之间,接下来比较5和16发现16>5,于是中位数在X:1,5和Y:9 16之间,然后比较16>5于是中位数在X:5和Y:9之间,由于上中位数,故而为9.

处理时使用递归方法,T(n)=2T(n/2)+O(1),于是T(n)=O(logn)

#include<iostream>using namespace std;int Find_Mid(int a[],int b[],int n);int main(){//测试int const n =4;int a[n] = {  3, 9, 47, 58 };int b[n] = { -9,5, 12, 78 };cout << Find_Mid(a, b,n) << endl;}int S_Mid(int a[], int b[], int pa, int pb, int l){if (l == 1 || a[pa + l / 2] == b[pb + l / 2])return a[pa+l/2] > b[pb+l/2] ? a[pa+l/2] : b[pb+l/2];if (a[pa + l / 2] > b[pb + l / 2])return S_Mid(a, b, pa, pb + l / 2, (l+1) / 2);   //用(l+1)/2奇偶可以一并处理elsereturn S_Mid(a, b, pa+l/2, pb, (l+1) / 2);}int Find_Mid(int a[], int b[], int n){return S_Mid(a, b, 0, 0, n);}

0 0
原创粉丝点击