• 查找第K大数


            所谓序列的第K大数就是对于一个给定的有N个元素的序列,为了讨论方便,假设序列元素值都不相同。这个序列的第1大数就是元素值最大的那个,第N大数就是元素值最小的那个。那么第2大就是除去最大值之外剩下元素中最大的那个。以此类推,可知第3大、第4大。。。。。。从描述中可以看出,对于查找序列的第K大数的问题,最直观的方法就是每次找到最大的那个,如果不是要找的,再从剩下的元素中再找最大的,如果还不是,则继续找。如此重复K次就能找到。那么除此之外,还有其他方法吗?

            可以借鉴归并排序的思路,从要查找的序列中每次随机挑一个值出来作为参考值,把序列中比它大的值放到这个值的左边,比它小的值放到这个值的右边。然后检查一下这个值在序列中的位置,如果正好等于K,那么它就是要找的值。如果它的位置比我们要找的K要大,那么说明第K大数位于该值左边的序列中,如果它的位置比K小,说明第K大数位于该值右边的序列中。这样我们就缩小了查找范围,然后在剩下的序列中继续采用这种方法查找,直到找到为止。

           以序列{11, 21, 9, 4, 33, 2, 18, 20}为例,假设我们要查找第3大元素。每次挑选第1个元素值作为参考值,对于这个序列是11。把大于11的元素都放到左边,小于11的元素都放到右边。得到序列{21,33,18,20,11,9,4,2}。11在调整后的序列中处于第5位,表示11是第5大元素。而我们要查找的是第3大元素。说明我们要找的元素在11左边的序列中,即{21,33,18,20}序列中。且在该序列中仍查找第3大元素。同样的,我们再以21作为参考元素,运用同样的规则得到{33,21,18,20}。21在该序列中处于第2位,表示21是该序列的第2大元素。而我们要查找的是第3大元素。说明我们要找的元素在21右边的序列中,即{18,20}序列中。且是该序列的第1大元素。注意,这里是需要查找第1大元素。因为21是第2大元素,所以第3大元素就是右边序列中的第1大元素。然后在{18,20}序列中重复之前的步骤,最后可以得到第3大元素就是20。

     1 //在一个序列中查找第K大元素
     2 #include <stdio.h>
     3 int findKthNum(int* array, int size, int k);
     4 int main(void){
     5     int array[] = {11, 21, 9, 4, 33, 2, 18, 20};
     6     for(int i = 1; i <= 8; i++){
     7         printf("第%d大元素是:%d
    ", i, findKthNum(array, 8, i));
     8     }
     9     return 0;
    10 }
    11 
    12 int findKthNum(int* array, int size, int k){
    13     int key = array[0];         //参考元素
    14     int flag = 0;               //标识每次移动元素的终点
    15     int index = 0;              //标识参考元素是第几大元素
    16     int tmp;
    17     for(int i = 1; i < size; i++){
    18         if(array[i] > key){
    19             tmp = array[i];
    20             for(int j = i; j > flag; j--){
    21                 array[j] = array[j-1];
    22             }
    23             array[flag] = tmp;
    24             flag = i;
    25         }
    26     }
    27     index = flag + 1;
    28     if(k == index){
    29         return array[flag];
    30     }else if(k > index){
    31         return findKthNum(&array[flag + 1], size - index, k - index);           //继续在右边序列中查找第k-index大元素
    32     }else{
    33         return findKthNum(array, index - 1, k);                                 //继续在左边序列中查找第k大元素
    34     }
    35 }

    这里使用的是移动数组元素的方法来最终确定参考元素的位置。flag是用来标识下一次移动数组元素的起点位置。

  • 相关阅读:
    大数据应用案例之医疗行业
    优先数调度:按最高优先级算法
    实验二:先来先服务进程调度
    实验一:熟练使用DOS操作命令实验
    考试管理搭建帮助文档
    介绍配置管理工具SVN的使用
    在VMware安装Windows server 2003操作系统帮助文档
    搭建一个考试管理系统
    WinMail邮件服务器(客户端)环境搭建与配置
    搭建OA项目环境及卸载指南
  • 原文地址:https://www.cnblogs.com/zhang-15-506/p/13258180.html
Copyright © 2020-2023  润新知