设想有一个20GB的文件,每一行一个字符串。说明如何将这个文件进行排序。php
思路1:外部排序,将部分数据载入内存。算法
将整个文件划分红许多块,每一个块xMB,其中x是可用的内存大小。每一个块各自进行排序,而后存回文件系统。各个块一旦完成排序,便将这些块逐一合并在一块儿,最终就能获得所有排好序的文件。排序
思路2:ip
内存确定没有20GB大,因此不可能采用传统排序法。可是能够将文件分红许多块,每块xMB,针对每一个块各自进行排序,存回文件系统。内存
而后将这些块逐一合并,最终获得所有排好序的文件。ci
外排序的一个例子是外归并排序(External merge sort),它读入一些能放在内存内的数据量,在内存中排序后输出为一个顺串(便是内部数据有序的临时文件),处理完全部的数据后再进行归并。[1][2]好比,要对900MB的数据进行排序,但机器上只有100 MB的可用内存时,外归并排序按以下方法操做:字符串
- 读入100 MB的数据至内存中,用某种常规方式(如快速排序、堆排序、归并排序等方法)在内存中完成排序。
- 将排序完成的数据写入磁盘。
- 重复步骤1和2直到全部的数据都存入了不一样的100 MB的块(临时文件)中。在这个例子中,有900 MB数据,单个临时文件大小为100 MB,因此会产生9个临时文件。
- 读入每一个临时文件(顺串)的前10 MB( = 100 MB / (9块 + 1))的数据放入内存中的输入缓冲区,最后的10 MB做为输出缓冲区。(实践中,将输入缓冲适当调小,而适当增大输出缓冲区能得到更好的效果。)
- 执行九路归并算法,将结果输出到输出缓冲区。一旦输出缓冲区满,将缓冲区中的数据写出至目标文件,清空缓冲区。一旦9个输入缓冲区中的一个变空,就从这个缓冲区关联的文件,读入下一个10M数据,除非这个文件已读完。这是“外归并排序”能在主存外完成排序的关键步骤 -- 由于“归并算法”(merge algorithm)对每个大块只是顺序地作一轮访问(进行归并),每一个大块不用彻底载入主存。