方法1_使用一个长度为10的基数组(冒泡排序省略):
定义一个长度为10的数组.当每从数组中拿出一个数据,就和长度为10的数组中的最小值进行比较.如果小于最小值,舍弃,否则插入到合适的位置.
伪代码如下:
A[N],a[m](分别为原始数组和降序数组,其中N=10000,m=10)
a = A[0 ... 9](将数组A的前10个数赋给数组a)
sort a(将组数a降序排序)
for i in A[ 10 ... N](从10到N遍历数组A)
if A[i] > a[9] then (如果当前值比降序数组中的最小值大)
删除a[9]
将A[i]插入a的合适位置,使a保持降序
end if
end for
输出数组a
(该方法也可将数组分段读取到内存.)
方法2_使用最小堆
最小堆
最小堆是一种完全二叉树,特点是根节点比两个子节点都小(或者根节点比子节点都大)
过程
- 先找10个数构建最小堆
- 依次遍历10亿个数,如果比最小堆的最小值大,则替换这个最小值,并重新构建最小堆
- 最后输入10个值
- 时间复杂度
构建最小堆的复杂度为 logn,求出最大m个数会构建m次最小堆,时间复杂度为 m logm, 这里m为10000
进行n次时间复杂度为n,这里n为10亿,总时间复杂度为 n m logm,即10亿 10000 log 10000
方法3_其他算法
- 将十亿个数排序,找出最大值,但是占用空间比较大,做了很多无用功
- 分治法:将10亿个数分成10份,求出每份的前10000个数 ,然后在这个10 * 10000 个数中找出最大的10000个数
- hash去重复,将这10亿个数的Hash值进行比较,去除重复的