分治法求第K大元素

k大元素不就是第(n-k+1)小元素么 = =

Code:
  1. #include<iostream>   
  2. #include<algorithm>   
  3. using namespace std;   
  4.     
  5. /***************************************  
  6. * 选择第k小元素算法  
  7. *  
  8. * 输入:元素数组A[],元素个数n,求的k  
  9. * 输出:第k小元素  
  10. ***************************************/  
  11. template<class Type>   
  12. Type select(Type A[], int n, int k){   
  13.         int i,j,s,t;   
  14.         Type m,*p,*q,*r;   
  15.         if(n<38){                     //     如果元素个数小于38:则直接排序   
  16.                 sort(A,A+n);   
  17.                 return A[k-1];   
  18.         }   
  19.         p = new Type[3*n/4];   
  20.         q = new Type[3*n/4];   
  21.         r = new Type[3*n/4];   
  22.         for( i=0; i<n/5; i++){  //        五个一组,把每组的中值元素存放进数组p   
  23.                 mid(A,i,p);   
  24.         }   
  25.         m = select(p, i, i/2+i%2);      //    递归调用,取得中值元素存入m   
  26.         i = j = s = 0;   
  27.         for( t=0; t<n; i++){    //  按<m、=m、>m把数组分成三组   
  28.                 if(A[t]<m){   
  29.                         p[i++] = A[t];   
  30.                 }else{   
  31.                         if(A[t]==m){   
  32.                                 q[j++] = A[t];   
  33.                         }else{   
  34.                                 r[s++] = A[t];   
  35.                         }   
  36.     
  37.                 }   
  38.         }   
  39.         if(i>k){                                //      若k<i,则该元素就在数组p中,进入p继续查找   
  40.                 return select(p,i,k);   
  41.         }else{   
  42.                 if(i+j>=k){               //   若i<k<i+j,则该元素在q数组中,即值为m   
  43.                         return m;   
  44.                 }else{        //        若k>i+j,则该元素在r数组中,进入r继续寻找   
  45.                         return select(r,s,k-i-j);   
  46.                 }   
  47.         }   
  48. }   
  49.     
  50. /***************************************  
  51. * 计算中值元素  
  52. *  
  53. * 输入:元素数组A[],组号i  
  54. * 输出:存放中值元素的数组p[]  
  55. ***************************************/  
  56. template<class Type>   
  57. void mid(Type A[], int i, Type p[]){   
  58.         int k = 5*i;   
  59.         if(A[k]>A[k+2]){   
  60.                 swap(A[k], A[k+2]);   
  61.         }   
  62.         if(A[k+1]>A[k+3]){   
  63.                 swap(A[k+1], A[k+3]);   
  64.         }   
  65.         if(A[k]>A[k+1]){   
  66.                 swap(A[k],A[k+1]);   
  67.         }   
  68.         if(A[k+2]>A[k+3]){   
  69.                 swap(A[k+2],A[k+3]);   
  70.         }   
  71.         if(A[k+1]>A[k+2]){   
  72.                 swap(A[k+1],A[k+2]);   
  73.         }   
  74.         if(A[k+4]>A[k+2]){   
  75.                 p[i] = A[k+2];   
  76.         }else{   
  77.                 if(A[k+4]>A[k+1]){   
  78.                         p[i] = A[k+4];   
  79.                 }else{   
  80.                         p[i] = A[k+1];   
  81.                 }   
  82.         }   
  83. }   
  84.     
  85. int main(){   
  86.         int n,m;   
  87.     
  88.         cout<<"请输入数组元素个数:";   
  89.         cin>>n;   
  90.           
  91.         cout<<"请输入要求的k:";   
  92.         cin>>m;   
  93.           
  94.         int *A = new int[n];   
  95.         int i;   
  96.     
  97.         cout<<"请输入数组元素:"<<endl;   
  98.         for(i=0;i<n;i++){   
  99.                 cin>>A[i];   
  100.         }   
  101.           
  102.         cout<<"第"<<m<<"大元素是:";   
  103.         cout<<select(A,n,n-m+1)<<endl;    // 输出第(n-m+1)小元素<=>第m大元素   
  104.     
  105.         return 0;   
  106. }  

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值