先通俗地说一下归并排序。打个比方,桌子上有两堆扑克牌,每堆扑克牌都是已经排好序的(不妨假设是升序)。我们从两堆扑克牌中各取最上面的一张(取的两张牌显然分别是两堆牌中最小的 ),比较大小,把最小的一张拿在手里,然后从“胜出”的牌所在的牌堆中再取一张。重复上面的过程。。。如果有一个牌堆被取完了,那么就把另一堆一股脑搬过来。这时候,你手中的牌就是升序的。换句话说,通过上面的算法,你成功把两个各为升序的牌堆合成了一个升序的牌堆——二合一。可以证明,该算法的复杂度是O(nlgn)。
上面所说的其实就是一个二路归并排序。显然,如果把k堆牌合成一堆,那就是k路归并排序。
考虑这样一个问题,我这里有k个文件,里面各自存储着已经排好序(不妨假设是升序)的,并且序相同的(要么都是升序要么都是降序)的整数。文件里的数据量很大,全部一股脑的装到内存里然后排序在输出是不现实的。这时候,就需要进行外排序,这时数据不会一次性全部进入内存。
在看接下来的内容之前,强烈建议读者在纸上演示一下,更能加深理解。
我们可以先建立一个败者树。所谓败者,就是在两两比较中不被选中的数,比方说我想要排成升序,那么两数之间较大的数就不会被选中,那它就是败者。b[i]表示从第i个文件中按顺序取出的数(类比