快排求第n_th元素

题目:输入n个整数和一个正整数k(0<=k<= n),输出这些整数从小到大排序后的第k个。n<=10^7。

首先我们可以先排序,然后返回a[k]。但是这样普通排序O(n^2)的复杂度是无法承受的,用O(nlogn)的排序方法,然后返回a[k]。有没有更高效的方法呢?有的,用快速排序,首先第一趟划分后,假设划分的位置为pos,那个左边有pos-1个数比他小。如果k==pos那么直接返回a[pos]。如果k<pos,那么kth_element肯定在左半边的数中,这样我们可以丢掉右边这些数据。同理如果k>pos,那么kth_elemetn则是在右边那些数中,这样把左边的数丢掉。这样的做我们只递归左半部分或者右半部分,复杂度为O(n)。下面是我写的模板,划分的方法采用一个比较简单的划分方法,网上还有hoare划分的方法,原理都一样。

 

int kth_element(int *a, int l, int r, int k){
  if(l < r){
    int key = a[r];
    int i = l-1;
    for(int j = l; j < r; j ++){
      if(a[j] < key){
        i ++;
        swap(a[i], a[j]);
      }
    }
    swap(a[i+1], a[r]);
    if(k == i+1) return a[i+1];
    else if(k < i+1) kth_element(a, l, i, k);
    else kth_element(a, i+2, r, k);
  }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值