在数组L[1....n]中找到第K小的元素

    显然,最直接的方法就是用排序算法对数组先进行从小到大的排序,然后直接提取L[k],便得到了第K小元素,但其平均时间复杂度将达到O(nlogn)以上。此外,还可以采用小顶堆的方法,每次堆定元素都是最小元素,时间复杂度为O(n+logn)。

     下面,介绍一个比较好的算法,它是基于快速排序的划分操作的。

      主要思想为:

      从数组L[1.....n]中选择Pivot(随机地或者直接取第一个)进行和快速排序一样的划分操作,表L[1.....n]被划分为L[1.....m-1]和L[m+1......n],其中L(m)=pivot;

      讨论m和k的大小关系:

  1)当m=k时,显然pivot就是所要寻找的元素,直接返回pivot就好。

  2)当m<k时,则所要寻找的元素一定落在L[m+1.....n]中,从而可以对L[m+1.....n]递归地查找第m-k小元素。

  3)当m>k时,则所要寻找的元素一定落在L[1......m+1]中,从而可以对L[1......m+1]递归地查找第K小元素。

这个算法的时间复杂度在平均的情况下可以达到O(n).

具体实现如下:

 1 int kth_elem(int a[],int low,int high,int k)
 2 {
 3   int pivot=a[low];
 4   int low_temp=low;
 5   int high_temp=high;
 6   while(low<high){
 7     while(low<high&&a[high]>=pivot){
 8       --high;
 9     }
10     a[low]=a[high];
11     while(low<high&&a[low]<=pivot){
12       ++low;
13     }
14     a[high]=a[low];
15   }
16   a[low]=pivot;
17   
18   //上面为快速排序中的划分算法
19   //  下面为本算法中所述内容
20   if(low==k){
21     return a[low];
22   }
23   else if(low>k){//在前一部分中递归查找
24     return kth_elem(a,low_temp,low-1,k);
25   }
26   else{//在后一部分递归查找
27     return kth_elem(a,low+1,high_temp,m-k);
28   }
29   
30 }

 

转载于:https://www.cnblogs.com/caizhk/articles/5284477.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值