求最小的K个数 O(N) 一种实现-基于堆排序

题目要求:给出一组数(有n个),求出前k个最小的数:

形式化描述如下:

给出一组数:c1,c2,...,Cn的无序排列A,设c1<c2<...<Cn,要求输出c1,c2,...,ck。

算法思想:用给定排列的前k个数建最大堆,对于后面的n-k个数,逐个进行判断,Ai(K<i<=n)

如果Ai<堆中最大数,则删除堆中最大数,插入Ai。这样到最后,序列A中的前k个最小数,就是堆中的k个数了

说白了,就是开始时认为序列中的前k个数就是这k个最小数,然后通过判断剩余的数,看看是否比这k个数中最大的

还小,若小则将其换出,这样到最后,被换出的数肯定比这k个数都大,所以,这k个数就是前k个最小数了;

建堆的复杂度为klogk+logk(n-k),因为k是常数,所以为O(N)

算法实现如下:

 

附上全部代码如下:

共两个文件,一个是最大堆得实现(MaxHeap.h),一个是算法实现与运行演示(theKthMins.cc):

注意:(将这两个文件放在同一目录下)

编译命令:g++ -o theKthMins theKthMins.cc MaxHeap.h
文件 MaxHeap.h 如下:
文件theKthMins.cc 如下:
运行结果如下:
[jim@gpu1 heap]$ g++ -o theKthMins theKthMins.cc MaxHeap.h
[jim@gpu1 heap]$ ./theKthMins
5       4       3       2       1
[jim@gpu1 heap]$

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值