随笔 - 113  文章 - 0  评论 - 218  阅读 - 73万

从一组数据中寻找第K大的数

问题描述:给出一组数据,如:整型数组 int a[]={10,1,3,6,9,39,20,12,33,54} 用尽可能快的方法找出第K大的位置(如:k=5时即第5大的数据应为12)。

分析问题:首先,如果求解问题是需要从一组数据寻找最值时(最大值或者最小值时)可能比较方便,一般作法是先排序,然后最首或者尾位置即可。

但现在需要求解的不一定是指最值,而是求第K大最值。那么同样处理思路是分步,即先排序然后求对应K位置。

 

经过简单的分析,下面给出Demo(C语言)

 //下面为排序设计两个函数

int partition(const int * na, int low, int hight);//标注位置

int qsort(const int * na, int low, int high, int nNeed);//改进快速排序 

/*

*寻找目标位置函数Find

*参数说明:

* narray:给定数组

* n:数组长度

* K:需要寻找第K大数值

*返回寻找的结果索引

*/

int Find(const int * narray, const int n, const int K)
{

  if ( n < 1)
    return -1;
  if ( (K < 1) || (K > n) )
   return -2;
  int * pN = new int[n];
  for (int i = 0; i < n; i++)

  {
     pN[i] = narray[i];

  }

  //在新数组中寻找第K最值数据(非索引位置)

  int nVal = qsort(pN, 0, n-1, k-1);


//在源数组中寻找第K最值索引位置

 for (int i = 0; i < n; i++)
  {
      if ( narray[i] == nVal)
        return i;
  }
}

 

/*

*  寻找索引位置,快速排序的位置处理部分

*/

int partition(const int * na, int low, int hight) {
  int nTmp = na[low];
 while (low < high )

 {
    while (low < high && na[high] <= nTmp)

      {
         high--;
      }
    na[low] = na[high];
    while (low < high && na[low] >= nTmp)
    {
        low++;
    }
  na[higt] = na[low];
 }
 na[low] = nTmp;
 return low;
}

 

/**
* 改造的快速排序算法,只排需要取得第K大前的元素。

*返回第K最值数据,不是索引位置
* 参数说明确:
* na : 指向数组索引.
* low : 所需要进行处理元素的下界

* hight :所需要进行处理元素的上界

* nNeed : 优先处理的元素.
*
*/
int qsort(const int * na, int low, int high, int nNeed) {
   int nFound = partition(na, low, high);
   if (nFound == nNeed)

   {
       return na[nFound];
    }

  if (nFound < nNeed) {
      return  qsort(na, nFound, high);
   }

  if (nFound > nNeed) {
     return  qsort(na, low, nFound);
  }
}

 

通过以上算法,我们可以快速实现求解过程,最好情况下时间复杂为:O(n),最差情况为:O(nlogn)。实现局部排序

但不知道还有没有其他更优化的算法。期待大家的回答

 

posted on   陈国利  阅读(2351)  评论(4编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2010年10月 >
26 27 28 29 30 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

点击右上角即可分享
微信分享提示