分析与解答:
假设:第k小的元素在x数组中,为x[mid] , 则有 y[k-mid] <= x[mid] <=y[k-mid+1] , 此时 k-mid >0
(1) 当 y[k-mid] <= x[mid] <= y[k-mid+1] 则 得到答案x[mid]
(2) 当 x[mid] < y[k-mid] 时,说时此时 x[mid] 太小了,low = mid+1
(3)当 x[mid] > y[k-mid+1]时, 说明此时x[mid]太大了,hight = mid - 1
所以查找时只要 先假设在 x中,查找一次,如果没找到 则在y中在查找一次就行了。
传入的参数中 high = min ( k, 查找数组长度)
假设a[m], b[n]是两个排好序的数组,并且没有重复元素,要找第k小的元素
思路如上,代码如下:
#include <iostream>
using namespace std;
int oneBiSearch(int* a,int *b,int low,int high,int K)
{
//假设第k大的数在a数组中
if(low > high) return -1;//没有的找到
int mid = low + (high-low)/2;
//注意防止 a[K] 越界
if(K==high && a[K] <= b[1])
return a[K];
if( a[mid] > b[K-mid] && a[mid]<b[K-mid+1] )
return a[mid];
if( a[mid] < b[K-mid] )
return oneBiSearch(a,b,mid+1,high,K);
if(a[mid] > b[K-mid+1])
return oneBiSearch(a,b,low,mid-1,K);
}
int BiSearch(int * a,int alen,int * b,int blen,int K)
{
if(alen+blen < K) return -1;
//每次 没必要传入整个数组,只要min(alen,K) 个就行了
int res = oneBiSearch( a,b,1,min(alen,K),K);
if(res == -1)
res = oneBiSearch(b,a,1,min(blen,K),K);
return res;
}
int main()
{
int a[6]={0,1,2,4,6,10};
int b[9]={0,3,5,7,8,9,11,12,16};
int K= 7;
int res = BiSearch( a,5,b,8,K);
cout<<res<<endl;
system("pause");
return 0;
}