zoukankan      html  css  js  c++  java
  • 从一组数据中寻找第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)。实现局部排序

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

  • 相关阅读:
    逆元应用求组合数
    树的重心入门
    扫描线求面积的并,交
    涂抹果酱
    牧场的安排
    「SCOI2005」互不侵犯
    Network Coverage
    Linux命令传输文件
    VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Device/Credenti
    Springboot开启SpringSecurity
  • 原文地址:https://www.cnblogs.com/cgli/p/1858472.html
Copyright © 2011-2022 走看看