• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
caizhk的爬坑之旅
博客园    首页    新随笔    联系   管理    订阅  订阅

在数组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 }

 

posted @ 2016-03-16 17:50  caizhk  阅读(877)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3