算法导论 9.3-8 寻找数组X[1..n],Y[1...n] 合并后的中位数

来源:互联网 发布:java面向对象编程pdf 编辑:程序博客网 时间:2024/05/21 15:47

题目:找两个已经排序的数组X[1..n],Y[1...n] 合并后的中位数,要求算法时间是logn。

稍微想了一下,利用中位数的思想来进行二分,这样就可以在logn的时间内找到中位数。按照这个思想写出来的代码在一定概率下能够找到中位数,但是有些情况发会发生常数项的偏移。后来看 “正在跟新昵称“ 童鞋的blog,发现他进行了很好地修正。 十分感谢。 附上代码:

#include <iostream>#include <cstdlib>#include <algorithm>#include <ctime>using namespace std;int * generateArray(int n);void printArray(int *A,int p,int r);void FindMiddle(int*A,int *B,int n);void vilentMiddle(int *A,int *B,int n);void FindMiddleB(int*A,int *B,int n);int main (){    srand(time(NULL));    int k = 15;    int *A = generateArray(k);    printArray(A,0,k);    int *B = generateArray(k);    printArray(B,0,k);    FindMiddle(A,B,k);    //FindMiddleB(A,B,k);    vilentMiddle(A,B,k);}int * generateArray(int n){    int *A = new int[n];    for (int i =0;i < n;i ++)    {        A[i] = rand();    }    sort(A,A+n);    return A;}void printArray(int *A,int p,int r){    for (int i = p;i < r;i ++)    {        cout << A[i] <<'\t';    }    cout <<endl << "--------------------------------" << endl;}void FindMiddle(int*A,int *B,int n){    int sa = 0,sb = 0;    int ea = n-1, eb = n-1;    int ma = 0,mb = 0;    if (A[n-1] <= B[0])    {        cout << A[n-1] << ' ' <<B[0] <<endl;        return;    }    if (B[n-1] <= A[0])    {        cout <<B[n-1] << ' ' << A[0] <<endl;        return;    }    while (sa < ea && sb<eb)    {        ma = (ea+sa)/2;        mb = (eb+sb)/2;        if (A[ma] < B[mb])        {            sa = ma;            eb = mb;        }        else        {            ea = ma;            sb = mb;        }    }    int t = ma + mb +2;    cout <<t <<endl;    cout << n-t << endl;    bool flag = false;    if (n-t > 0)//进行修正    {        for (int i = 1; i <= n-t; i ++)        {            ++ma;            ++mb;            if(A[ma] < B[mb])            {                cout << "as" << A[ma] << ' '<< B[mb] <<  endl;                --mb;                flag = false;            }            else            {                cout << "ds" << A[ma] << ' '<< B[mb] <<  endl;                --ma;                flag = true;            }        }        if (flag)        {            cout << B[mb] <<endl;        }        else        {            cout << A[ma] << endl;        }    }    else    {        if (A[ma] < B[mb])        {            cout << B[mb] <<endl;        }        else        {            cout <<A[ma] << endl;        }    }   // cout << A[ma] << ' ' << B[mb] <<endl;   /* if (true)    {        cout << A[sa] << ' ' << A[ea] <<endl << B[sa] << ' ' << B[ea] <<endl;    }    else{        cout << A[ma] <<endl;    }*/}void FindMiddleB(int*A,int *B,int n){    int sa = 0,sb = 0;    int ea = n-1, eb = n-1;    int ma = 0,mb = 0;    if (A[n-1] <= B[0])    {        cout << A[n-1] << ' ' <<B[0] <<endl;        return;    }    if (B[n-1] <= A[0])    {        cout <<B[n-1] << ' ' << A[0] <<endl;        return;    }    while (sa < ea && sb<eb)    {        ma = (ea+sa+1)/2;        mb = (eb+sb+1)/2;        if (A[ma] < B[mb])        {            sa = ma;            eb = mb;        }        else        {            ea = ma;            sb = mb;        }    }    int t = ma + mb +2;    cout <<t <<endl;    cout << n-t << endl;    cout <<A[ma] << ' ' << B[mb] <<endl;    bool flag = false;    if (t-n-1> 0)    {        for (int i = 1; i <= t-n-1; i ++)        {            --ma;            --mb;            if(A[ma] < B[mb])            {                cout << "as" << A[ma] << ' '<< B[mb] <<  endl;                ++ma;                flag = false;            }            else            {                cout << "ds" << A[ma] << ' '<< B[mb] <<  endl;                ++mb;                flag = true;            }        }        if (flag)        {            cout << B[mb] <<endl;        }        else        {            cout << A[ma] << endl;        }    }    else    {        if (A[ma] < B[mb])        {            cout << B[mb] <<endl;        }        else        {            cout <<A[ma] << endl;        }    }   // cout << A[ma] << ' ' << B[mb] <<endl;   /* if (true)    {        cout << A[sa] << ' ' << A[ea] <<endl << B[sa] << ' ' << B[ea] <<endl;    }    else{        cout << A[ma] <<endl;    }*/}void vilentMiddle(int *A,int *B,int n){    int *C = new int[2*n];    for (int i = 0;i < n;i ++)    {        C[i] = A[i];        C[i+n] = B[i];    }    sort(C,C+2*n);    cout << C[n-1] <<' ' <<C[n] << endl;    printArray(C,0,2*n);    delete []C;}

上面一段代码中,修正最终结果的那段代码虽然是可以用的,但是不知道怎么推出来的。囧。


0 0