外部排序

来源:互联网 发布:js 变量字符串拼接 编辑:程序博客网 时间:2024/04/28 04:43

转自http://blog.csdn.net/rongyongfeikai2/article/details/7490252

一般而言,讨论的排序,都是将数据读入内存之后进行的排序。不管是快速排序、堆排序、归并排序还是插入排序,耳熟能详的冒泡排序。当然,在内部排序中,效果最好的当属快速排序,虽然它在输入大致有序的情况下会有O(n*n)这样比较差的时间复杂度。

稳定的排序:插入排序、归并排序;不稳定的排序:快速排序、Shell排序、堆排序。

现在讨论外部排序,所谓外部排序,就是待排序的数据不能够一次性放入主存,故需多次读入主存进行排序。

归并排序是外部排序的核心思想。

例如有一组数:81,94,11,96,12,35,17,99,28,58,41,75,1513个数,而每次只能读入内存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

再依次将Doc2Doc3中的数归并如Doc1;具体的过程为,首先去Doc2的第一个和Doc3的第一个放入内存,进行比较,将小的写入Doc1;再将写入Doc1的数字所在的文档中的数字读取出一个;重复进行,直至完Doc2Doc1中的一个顺串。(此时归并所耗的内存为2*4JAVA int型占4个字节)。

Doc1:11,17,28,81,94,99

Doc2:12,35,96

Doc3:41,58,75|15

按照上面叙述的同样的方法,将Doc2Doc3中的顺串归并到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:

再将Doc1Doc2归并入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

归并即完成。

多路归并亦是同样的思想。

至于如何读取文档的指定行,可以就是顺序遍历读取(……)应该浪费比较多的时间吧…..但是为了外部排序的完成,只好牺牲时间了。

如有更好的办法,还望赐教。

0 0
原创粉丝点击