内排序算法我们学了很多,快速排序、冒泡排序等。这些排序的前提是数据量不大,能够全部读进内存里。外排序是指对大数据量进行排序,数据量大到不能全部读进内存里,必须在内存和外存间换进换出进行排序。
最常用的外排序法是归并法。举个例子,对900M的数据进行外排序,但内存只有100M。排序过程:
1、将原数据分组进行排序,每组100M,一共9组。排序过程是读100M进内存,对这100M进行内排序(用快速排序等),然后输出到外存的一个临时文件。接下来读下一个100M。
2、步骤1产生了9个排好序的临时文件。将100M内存分为10个10M的buffer,其中9个作为9个输入文件的buffer,另外一个10M内存作为输出buffer,然后做9路归并排序。
回想一下以前学的内排序中的归并排序,与归并法外排序做比较。 发现他们差别是:
1、内排序中的归并排序是两个两个做归并组成一个大的有序数组然后接着和大数组进行归并。
2、外排序中的归并排序做9路归并,一次性归并完。
这种做法的好处是减少对硬盘的读写次数。多路归并时对每一个数据只进行一次硬盘读写,若是像内排序中的归并那样直要有多次的读写硬盘。
谨记,现代计算机中的程序,瓶颈基本上是在IO,而不在于CPU。
事实上,这里有一个问题需要权衡。太多路同时进行归并也会有问题。我们的例子中,输入buffer每次可以读取10M的数据。但如果数据真的特别大,以至于多路归并时内存分了太多个buffer,导致每个buffer很小每次只能读入很小的数据比如说1K,这种情况性能也会大大降低的。这时候就需要做多次的归并,比如说对于1个100G的输入数据,可以一个G一个G的做归并外排序然后存到外存临时文件里,然后再对这10个G做一个10路归并。
原文地址:http://blog.sina.com.cn/s/blog_64972ef20100zcmi.html