转自http://blog.csdn.net/rongyongfeikai2/article/details/7490252
一般而言,讨论的排序,都是将数据读入内存之后进行的排序。不管是快速排序、堆排序、归并排序还是插入排序,耳熟能详的冒泡排序。当然,在内部排序中,效果最好的当属快速排序,虽然它在输入大致有序的情况下会有O(n*n)这样比较差的时间复杂度。
稳定的排序:插入排序、归并排序;不稳定的排序:快速排序、Shell排序、堆排序。
现在讨论外部排序,所谓外部排序,就是待排序的数据不能够一次性放入主存,故需多次读入主存进行排序。
归并排序是外部排序的核心思想。
例如有一组数:81,94,11,96,12,35,17,99,28,58,41,75,15这13个数,而每次只能读入内存4个数,如何进行排序呢?
假设我们新建了3个文本文档,每一行用于存储1个数。分别将这3个文档命名为doc1,doc2,doc3。
假设最初始的情况,这13个数在doc1中。
我们按照6+7的划分原则进行划分。
首先3个一排序的将前六个数作为2个顺串存入doc2;再3个一排序,将后7个数作为3个数存入doc3。得到的结果为:
Doc1: 81,94,11,96,12,35,17,99,28,58,41,75,15;
Doc2:11,81,94|12,35,96;
Doc3:17,28,99|41,58,75|15
再依次将Doc2和Doc3中的数归并如Doc1;具体的过程为,首先去Doc2的第一个和Doc3的第一个放入内存,进行比较,将小的写入Doc1;再将写入Doc1的数字所在的文档中的数字读取出一个;重复进行,直至完Doc2和Doc1中的一个顺串。(此时归并所耗的内存为2*4,JAVA int型占4个字节)。
Doc1:11,17,28,81,94,99
Doc2:12,35,96
Doc3:41,58,75|15
按照上面叙述的同样的方法,将Doc2和Doc3中的顺串归并到Doc2中。得到:
Doc1:11,17,28,81,94,99
Doc2:12,35,41,58,75,96
Doc3:15
将Doc3归并入Doc2:
Doc1:11,17,28,81,94,99
Doc2:12,15,35,41,58,75,96
Doc3:
再将Doc1和Doc2归并入Doc3:
Doc1:11,17,28,81,94,99
Doc2:12,15,35,41,58,75,96
Doc3:11,12,15,17,28,35,41,58,75,81,94,96,99
归并即完成。
多路归并亦是同样的思想。
至于如何读取文档的指定行,可以就是顺序遍历读取(……)应该浪费比较多的时间吧…..但是为了外部排序的完成,只好牺牲时间了。
如有更好的办法,还望赐教。