怎样对千万级甚至亿级数据量排序

编程珠玑第二版第一章就有相似的问题,问题描述以下:算法

有最多1000万条不一样的整型数据存在于硬盘的文件中(数据不超过最大值),如何在1M内存的状况下对其进行尽量快的排序。编程

数据特征:单个数据<=1000万、不一样的(没有重复)、整型(int,4B)

要求:1M内存、尽量快

分析:1MB = 1*1024*1024 B   能存储大于25万个int类型的整数。因此每次咱们能够排序25万条记录,一共排序40次。

 

(1)一个简单的思路是读1000万条1次,对第i个25万条数据进行排序,并将排好的结果存成外部文件i(这里能够用常见的内部排序,如快排),最后咱们生成了40个排好序的外部文件,而后对这40个文件进行归并排序输出成1个文件。数据结构

 

(2)更好的思路是位向量排序,咱们能够申请一个1千万长度的位向量bit[10000000],全部位设置为0,顺序读取待排序文件,每读入一个数i,便将bit[i]置为1。当全部数据读入完成,便对 bit作从头至尾的遍历,若是bit[i]=1,则输出i到文件,当遍历完成,文件则已排好序。spa

这个思路和桶排序同样,算法的关键是位向量。对于不支持bit数据结构的语言咱们能够本身实现位操做,int是32位的,因此咱们须要[1千万/32+1]个int类型存储,大约1.2M。(虽然差点不符合题目的要求,可是不失为一种更好的解题思路)。code

将第i位置为1的时候能够用以下操做:对象

a[i/32] | (1 << (i%32)); 

第i位确定在i/32个int上,i%32是偏移量,而后经过按位或来将特定位置1。(不明白的能够了解一下位计算)blog

为了计算速度更快,上述公式能够彻底由位运算替代:排序

a[i >>5] |= (1 << (i & 31));

 

总结内存

对于大的数量级的排序,基本思路是分而治之的思想,位向量方法虽然效率很高,可是要注意一些限制条件(数据不能重复、不适合稀疏的数据分布等)。hash

编程珠玑中的例子是int型的数据排序,实际咱们面临的问题可能不会这么简单,例如须要对复杂数据类型进行排序(对象),咱们可让对象实现compareTo,重写hashcode、equals等等。

相关文章
相关标签/搜索