查找无序数中最大k个数

这篇博客介绍了如何在无序数组中查找最大的k个数。通过快速选择算法找到数组中第k大的元素,并给出了具体实现。此外,还提供了使用最小堆寻找数组中最大k个数的方法,确保了在不断插入新元素时保持堆的性质。
摘要由CSDN通过智能技术生成
解法一:该解法是大部分能想到的,也是第一想到的方法。假设数据量不大,可以先用快速排序或堆排序,他们的平均时间复杂度为O(N*logN),然后取出前K个,时间复杂度为O(K),总的时间复杂度为O(N*logN)+O(K).
        当K=1时,上面的算法的时间复杂度也是O(N*logN),上面的算法是把整个数组都进行了排序,而原题目只要求最大的K个数,并不需要前K个数有限,也不需要后N-K个数有序。可以通过部分排序算法如选择排序和交换排序,把N个数中的前K个数排序出来,复杂度为O(N*K),选择哪一个,取决于K的大小,在K(K<logN)较小的情况下,选择部分排序。
解法二:(掌握)避免对前K个数进行排序来获取更好的性能(利用快速排序的原理)。
        假设N个数存储在数组S中,从数组中随机找一个元素X,将数组分成两部分Sa和Sb.Sa中的元素大于等于X,Sb中的元素小于X。
    出现如下两种情况:
   (1)若Sa组的个数大于或等于K,则继续在sa分组中找取最大的K个数字 。
   (2)若Sa组中的数字小于K ,其个数为T,则继续在sb中找取 K-T个数字 。
   一直这样递归下去,不断把问题分解成小问题,平均时间复杂度为O(N*logK)。
   代码如下:
  1. void partition(int a[], int s,int t,int &k) 

  2. int i,j,x; 
  3. x=a[s]; //取划分元素 
  4. i=s; //扫描指针初值 
  5. j=t; 
  6. do 

  7. while((a[j]<x)&&i<j) j--; //从右向左扫描,如果是比划分元素小,则不动
  8. if(i<j) a[i++]=a[j]; //大元素向左边移 
  9. while((a[i]>=x)&&i<j) i++; //从左向右扫描,如果是比划分元素大,则不动 
  10. if(i<j) a[j--]=a[i]; //小元素向右边移 

  11. }while(i<j); //直到指针i与j相等 
  12. a[i]=x; //划分元素就位 
  13. k=i; 

  14. /*查找数组前K个最大的元素,index:返回数组中最大元素中第K个元素的下标(从0开始编号),high为数组最大下标*/
  15. int FindKMax(int a[],int low,int high,int k)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值