用快速排序的思想求第K大的数或最大的k个数

  1. 利用快速排序的特点:第一遍排序会确定一个数的位置,这个数左边都比它大,右边都比他小(降序),当左边区间大于K时,说明我们求的第K大数在左边区间,这时我们可以舍弃右边区间,将范围缩小到左边区间从而重复上述过程,直到确定一个数的位置时,左边区间的小是K-1那么这个数字就是我们所求。右边同理。

     能够使用这种方法的前提条件是:n个数不能重复。如果n个数中有重复,那么区间的大小不能保证就是第K大。可以用HASH判重来将重复的数据去掉。然后再使用上述方法。


  2. #include <iostream>  
  3. using namespace std;  
  4. template <class T>  
  5. int quick2_sort(T a[],int low,int high)  
  6. {  
  7.     T temp=a[low];  
  8.     int pos=low;  
  9.     int i=low,j=high;  
  10.     while(i<j)  
  11.     {  
  12.         while(i<j && a[j]>temp)  
  13.             j--;  
  14.         if(i<j)  
  15.         {  
  16.             a[pos]=a[j];  
  17.             pos=j;  
  18.         }  
  19.         while(i<j && a[i]<temp)  
  20.             i++;  
  21.         if(i<j)  
  22.         {  
  23.             a[pos]=a[i];  
  24.             pos=i;  
  25.         }  
  26.     }  
  27.     a[pos]=temp;  
  28.     return pos;  
  29. }  
  30.   
  31.  //递归实现
    int findkth(int* arr, int begin, int end, int k)
    {
    int pos = partition(arr, begin, end);
    //递归的结束条件为某一记录刚好划分到第k个位置
    //由于数组从0开始,所以需要加1了
    if (pos == k-1)
    {
    return arr[pos];
    }
    else if (pos < k-1)
    {
    findkth(arr, pos+1, end, k);
    }
    else
    {
    findkth(arr, begin, pos-1, k);
    }
    }
     
  32. //利用快速排序的思想查找第K大的数值  
  33. //第一个参数代表要查找的数组  
  34. //第二个参数代表数组的长度  
  35. //第三个参数代表要查找第几大的元素  
  36. //非递归
  37. template <class T>  
  38. T findkth(T a[],int n,int k)  
  39. {  
  40.     int low=0,high=n-1;  
  41.     while(1)  
  42.     {  
  43.         int pos=quick2_sort(a,low,high);  
  44.         if(pos==n-k)  
  45.             return a[pos];  
  46.         else if(pos<n-k)  
  47.         {  
  48.             low=pos+1;  
  49.             high=n-1;  
  50.         }  
  51.         else if(pos>n-k)  
  52.         {  
  53.             high=pos-1;  
  54.             low=0;  
  55.         }  
  56.     }  
  57. }  
  58.   
  59. int main()  
  60. {  
  61.   
  62.     int a[11]={78934,234,65,32,543,354,567,3412,23,547,423};  
  63.     cout<<findkth(a,11,4)<<endl;  
  64.     return 0;  
  65. }  
最大的k个数即第k大数右边所有的数(包括自身)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值