题目
一个长度为L(L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数为11。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。
题解
分析
1. 升序序列
首先,要将两个序列进行归并排序,使用函数Merge()。
2. Merge()
功能:将两个有序序列归并成为一个。
利用辅助动态数组B,将A的两段(各自有序)存入B,比较B中两段数组,较小值存回A
int *B = (int *)malloc(n*sizeof(int)); //定义辅助数组B
void Merge(int A[], int low, int mid, int high){
for(int i=low;i<high;i++){
B[i]=A[i];
} //将A复制到B中
for(int m=low,int n=mid+1,int k=low;m<=mid&&n<=high;k++){
if(B[m]<B[n]){
A[k]=B[m];
m++;
}
else{
A[k]=B[n];
n++;
}
}
while(m<=mid){A[k++]=B[m++]}
while(n<=high){A[k++]=B[n++]} //将剩余部分填充
}
3. 序列A和B中位数
长度L/2向下取整
代码
int *C = (int *)malloc(n*sizeof(int)); //定义辅助数组B
void Merge(int A[], int B[], int L){
for(int i=0,int m=0,int n=0;i<2*L;i++){
if(A[m]<B[n]){
C[i]=A[m++];
}
else{
C[i]=B[n++];
}
}
}
void main(){
Merge(A,B,L);
cout<<C[L-1];
}