排序算法--位图算法

最近在看Jon Bentley的《编程珠玑》,刚看完第一章,觉得老外写的东西就是要比国内的生动很多! 第一章是开篇,要说的事情是:要把问题描述清楚。为了说明白这个事情,作者举了一个实例:怎样给一个磁盘文件排序? 这个问题问的很模糊是不是? 其实这个问题正确清楚的描述如下:


输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10,000,000。输入文件中没有重复的整数,没有其他数据与该整数相关联(这句话不知道是想说什么问题..)。

输出: 按升序排列这些数,并写入磁盘。

约束:有 1MB多(不超过2MB) 的内存空间可用,有充足的硬盘空间。


在刚开始需要解决这个问题的时候,作者想到了磁盘的归并排序(这个我还不知道,囧)、多趟算法,后来在想清楚了问题之后,找到了一个快速的算法:位图排序。(貌似我很罗嗦..)。

1MB 内存可以存放1024*1024/4 =262144个int类型的值。就是说如果文件中包含的整数个数很大,那么2MB的内存空间是完全放不下的,那么可以考虑多趟排序。多趟排序的描述如下:

由于1M内存最多放262144个int,那么第一趟读一篇文件,取出0-249999之间的数放入内存,进行排序,排序算法可以使用快速排序,排序完写入硬盘。第二趟读一遍文件,将250000-499999之间的数都读到内存,在进行排序,写入硬盘.....,一直到所有数据都排序完。这样能做到排序的目的,但是由于多次读文件带来了巨大的开销。

对于这种问题的最好算法应当是位图:由于整数没有重复,那么可以用比特位来表示整数的存在。

比如集合 {1,2,5,4,7},

可以用位图表示为   01101101,

由于位图的第1,2,4,5,7为都是1,表示集合里存在着这几个数。

具体到这个算法实现的时候,由于数最大为10 000 000,那么可以用10 000 000个bit的数组来表示,内存大小为 10 000 000/8/1024/1024=1.19MB的内存空间。

排序算法如下:

1.根据需要排序的输入中最大和最小的数,设置byte型的数组(为什么不是bit型呢?因为计算机处理的最小单元就是byte..1byte=8bit),设置所有位为0。

2.依次读取输入,某一次读取数据是,在数组那一位设置1,表示包含这个数。

3.读回,遍历byte数组,如果某一位是1,就表示包含这个数。

注:涉及到的位操作可以参考《编程珠玑》习题1.6的第二题。



你可能感兴趣的:(编程,算法,byte,磁盘)