面试题之10亿正整数问题续--关于多通道排序的问题
因为原来的文章没人回,所以只好开了这个文章,希望看的人多些,给一下解答。
原来的文章为面试题之10亿正整数问题,其实其基本都是从《编程珠玑》上面修改而来的,只是问题的规模变大了而已。但是在仔细研究《编程珠玑》中的解法时,发现是不是因为说得太简略,对于其中介绍的多通道排序并不是很理解。
这里因为前面的文章已经将问题介绍得比较清楚了,所以就简单将整理之后的问题描述如下:
【整理之后,精确的问题陈述】 输入: 所输入的是一个文件,至多包含n个正整数,每个正整数都要小于n,这里的n为10^7。如果输入时某一个整数出现了两次,就会产生一个致命的错误。这些整数与其他任何数据都不关联。 输出: 以增序形式输出经过排序的整数列表。(这里应该补充一下是文件形式吗?) 约束:
至多(大概)只有1MB的可用主存,但是可用磁盘空间非常充足。运行时间至多只允许几分钟,最适宜的时间大概为10秒钟。
作者一共介绍了3种解法,一是归并排序,二是多通道排序,三是叫做精彩排序的方法。
关于归并排序,并没有什么问题,使用分而治之的方法,将输入文件分为若干段,然后对每一段使用内排序,并输出到中间文件中,最后对这些中间文件进行合并,生成一个最终排序好的输出文件。
这里对输入文件会读取一次,对中间文件会操作多次(读取和写入),对输出文件会写入一次。
但是对于多通道排序,从作者的描述来看,似乎和归并排序差不多,没太理解明白,为什么作者说,我们不需要使用中间磁盘文件,但是需要多次读取输入文件。
对于多通道排序,作者的描述如下:
因为一共有10000000个整数,而1M中我们使用250000个号码存储,所以需要使用40个通道。 第一个通道中将0到249999之间的任意整数读到内存中,并对这250000个整数进行排序,然后将它们写入输出文件中。 第二个通道对250000到499999之间的整数进行排序,然后也是同样写入输出文件中。 依次类推,直到第40个通道。 第40个通道将排序9750000到9999999之间的整数,然后写入输出文件中。 注意,这里意思是输出文件是同一个文件。 快速排序在主存中相当有效,它只需要20行代码。因此整个程序只需1到2页的代码即可实现,并且该程序还有一个令人满意的特性,即我们不必担心使用中间磁盘文件的问题。
40个通道的算法不使用中间文件,需要多次读取输入文件,但只进行一次输出文件的写入操作。
这里就有些不太明白,为什么不用中间文件,不用中间文件的话,具体是如何操作的?
多通道排序,其英文为multi-pass sort,或者multiple pass sort。从查到的资料来看,似乎数据库中使用较多,在一些Oracle的教程中,有cache sort, one-pass sort和multi-pass sort的说法,但是一是不清楚这里所说的多通道排序是否是数据库中的这个,还有就是从数据库中那里来看,也似乎没有说不需要使用中间文件。
大家有没有了解这个的呢?能否解释解释,想得头疼~~
关于sort搜索到的资料,in memory sort就是cache sort.
in memory sort Everything fits in memory, no disk is needed, everything done in ram.
one pass sort We read some amount of data and sort it, the sort workarea fills up, we write that to disk. We do it again (read more, sort it) - this too spills to disk. We do this over and over until we've read the entire set of data and sorted each of the chunks. Now we need read a bit of each of the chunks we've sorted on disk and start returning data from there. In the one pass sort, we can read a bit of each chunk and start returning data. If we cannot read a bit of EVERY chunk then....
we are in the realm of the multi-pass sort. We read and merge the first few chunks - resulting in a new set. We read and merge another set of chunks - resulting in a new set. And so on - until we've processed all of the output from the first pass and created a "second pass" of more merged (more sorted) data. Then we merge those in the sort area and start returning data.
参考地址:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1308127400346936009