两个已经排序号的数组内,找第k大个元素

假设:第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 = low+1

(3)当 x[mid] > y[k-mid+1]时, 说明此时x[mid]太大了,hight = high - 1   

所以查找时只要 先假设在 x中,查找一次,如果没找到 则在y中在查找一次就行了。

传入的参数中 high  = min ( k, 查找数组长度)

 

假设a[m], b[n]是两个排好序的数组,并且没有重复元素,要找第k小的元素

思路如上,代码如下:

  1. #include <iostream>   
  2. usingnamespace std;   
  3.  
  4. int oneBiSearch(int* a,int *b,int low,int high,int K)   
  5. {   
  6.    
  7.   //假设第k大的数在a数组中   
  8.   if(low > high) return -1;//没有的找到   
  9.   int mid = low + (high-low)/2;   
  10.   //注意防止 a[K] 越界  
  11.   if(K==high && a[K] <= b[1])    
  12.       return a[K];   
  13.   if( a[mid] > b[K-mid] &&  a[mid]<b[K-mid+1] )    
  14.       return a[mid];  
  15.         
  16.   if( a[mid] < b[K-mid] )    
  17.      return oneBiSearch(a,b,mid+1,high,K);   
  18.      
  19.   if(a[mid] > b[K-mid+1])   
  20.       return oneBiSearch(a,b,low,mid-1,K);   
  21.            
  22. }   
  23.  
  24. int BiSearch(int * a,int alen,int * b,int blen,int K) 
  25.     if(alen+blen < K) return -1; 
  26.   //每次 没必要传入整个数组,只要min(alen,K) 个就行了  
  27.     int res = oneBiSearch( a,b,1,min(alen,K),K);   
  28.   
  29.     if(res == -1)   
  30.     res = oneBiSearch(b,a,1,min(blen,K),K); 
  31.      
  32.     return res; 
  33.  
  34. int main()   
  35. {   
  36.     int a[6]={0,1,2,4,6,10};   
  37.     int b[9]={0,3,5,7,8,9,11,12,16};   
  38.     int K= 7;   
  39.     int res = BiSearch( a,5,b,8,K);   
  40.      
  41.     cout<<res<<endl;   
  42.     system("pause"); 
  43.     return 0;   
  44. }   

posted @ 2012-06-27 11:13  springbarley  阅读(214)  评论(0)    收藏  举报