归并排序算法简要介绍:
一、思路描述:
设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。
二路归并排序的过程是:
(1)把无序表中的每一个元素都看作是一个有序表,则有n个有序子表;
(2)把n个有序子表按相邻位置分成若干对(若n为奇数,则最后一个子表单独作为一组),每对中的两个子表进行归并,归并后子表数减少一半;
(3)反复进行这一过程,直到归并为一个有序表为止。
二路归并排序过程的核心操作是将一维数组中相邻的两个有序表归并为一个有序表。
二、分类:
归并排序可分为:多路归并排序、两路归并排序 。
若归并的有序表有两个,叫做二路归并。一般地,若归并的有序表有k个,则称为k路归并。二路归并最为简单和常用,既适用于内部排序,也适用于外部排序。本文着重讨论外部排序下的多(K)路归并算法。
三、算法分析:
1、稳定性:归并排序是一种稳定的排序。
2、存储结构要求:可用顺序存储结构。也易于在链表上实现。
3、时间复杂度: 对长度为n的文件,需进行lgn趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。。
4、空间复杂度:需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
注意:若用单链表做存储结构,很容易给出就地的归并排序。
总结:与快速排序相比,归并排序的最大特点是,它是一种稳定的排序方法。归并排序一般多用于外排序。但它在内排方面也占有重要地位,因为它是基于比较的时间复杂度为O(N*Log(N))的排序算法中唯一稳定的排序,所以在需要稳定内排序时通常会选择归并排序。归并排序不要求对序列可以很快地进行随机访问,所以在链表排序的实现中很受欢迎。
在多路归并中,用到了败者树这个概念。留心!http://blog.163.com/yangjun1988422@126/blog/static/474129172011711103313483/
关于败者树,有两个地方需要注意:
1 为什么败者树效率优于胜者树? 个人认为:胜者树的维护需要比较兄弟节点,问题是兄弟节点在哪个位置是不容易计算的。败者树的更新需要比较父节点,这是非常容易计算位置的。
2 败者树和堆的比较,谁的效率高呢? 参考一个博客:http://blog.csdn.net/httphttpcn/article/details/6075999
1 败者树在进行维护的时候,比较次数是logn+1。与堆不同的是,败者树是从下往上维护,每上一层,只需要和败者节点比较“一次”即可。而堆在维护的时候是从上往下,每下一层,需要和左右子节点都比较,需要比较两次。从这个角度,败者树比堆更优一些。
2 但是,请注意但是,败者树每一次维护必定需要从叶子节点一直走到根节点,不可能中间停止;而堆维护时,“有可能”会在中间的某个层停止,不需要继续往下。这样一来,虽然每一层败者树需要的比较次数比堆少一倍,但是走的层数堆会比败者树少。具体少多少,从平均意义上到底哪一个的效率会更好一些?那我就不知道了,这个分析起来有点麻烦。感兴趣的人可以尝试一下,讨论讨论。但是至少说明了,也许堆并非是最优的。
3 在空间复杂度上,败者树所需的空间大小是堆的一倍。