题目:设有两个已排好序的数组,设计一个O(logn)时间算法,找出X和Y数组的2n个数的中位数。
#include <stdio.h>
void Mid_Num( int a[] , int b[] , int n )
{
int n1 , left1 , left2 , right1 , right2 ;
float m1 , m2 , m ;
left1 = left2 = 0 ;
right1 = right2 = n-1 ;
n1 = n;
while( n1 > 2 )
{
if( n1 % 2 == 0 ) //if the number is not odd
{
m1 = ( a[left1 + n1/2] + a[left1 + (n1 - 1)/2] ) / 2 ; //the mid number is (a[n-1/2] + a[n/2])/2
m2 = ( b[left2 + n1/2] + b[left2 + (n1 - 1)/2] ) /2 ;
if( m1 > m2 )
{
right1 = left1 + ( n1 - 1 )/2 ;
left2 = left2 + n1/2 ;
}
else
{
left1 = left1 + n1/2 ;
right2 = left2 + ( n1 - 1 )/2 ;
}
n1 = ( n1 + 1 )/2 ;
}
else
{
m1 = a[left1 + n1/2] ; //if the number is odd,the mid number is a[n/2]
m2 = b[left2 + n1/2] ;
if( m1 > m2 )
{
right1 = left1 + n1/2 ;
left2 = left2 + n1/2 ;
}
else
{
left1 = left1 + n1/2 ;
right2 = left2 + n1/2 ;
}
n1 = ( n1 + 1 )/2 ;
}
// printf( "m1 = %f,m2 = %f\n",m1,m2 ) ;
}
// printf( "a[left1] = %d,a[right1] = %d\nb[left2] = %d,b[right2] = %d\n ",a[left1],a[right1],b[left2],b[right2] ) ;
if( n1 == 2 )
{
if( a[right1] <= b[left2] )
m = ( a[right1] + b[left2] )*1.0 /2 ;
else if( a[left1] <= b[left2] )
{
if( a[right1] <= b[right2] )
m = ( a[right1] + b[left2] )*1.0 / 2 ;
else
m = ( b[left2] + b[right2] )*1.0 / 2 ;
}
else if( a[left1] <= b[right2] )
{
if( a[right1] <= b[right2] )
m = ( a[left1] + a[right1] )*1.0 / 2 ;
else
m = ( a[left1] + b[right2] )*1.0 / 2 ;
}
}
printf( "m = %f\n",m );
}
int main( void )
{
int i , n ;
printf( "please input n:\n" ) ;
scanf( "%d",&n ) ;
int a[n] , b[n] ;
printf( "please input %d number sort arry a:\n",n ) ;
for( i = 0 ; i < n ; i++ )
scanf( "%d",a+i ) ;
printf( "please input %d number sort arry b:\n",n ) ;
for( i = 0 ; i < n ; i++ )
scanf( "%d",b+i ) ;
Mid_Num( a , b , n ) ;
return 0 ;
}
分治算法的基本思想:将大规模地问题分解为k个规模小的问题,且每个小问题与原问题相似。