您的位置:首页 > 其它

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

2014-05-05 22:46 417 查看
题目:找两个已经排序的数组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
;
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
<< endl;
printArray(C,0,2*n);
delete []C;
}


上面一段代码中,修正最终结果的那段代码虽然是可以用的,但是不知道怎么推出来的。囧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: