归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程分解

假设两个有序表分别为a,b,最后归并到r表中。

归并过程:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

示例分解

假设原始序列为:{6,202,100,301,38,8,1},其长度len = 7,归并过程:

1、第一次归并:先中分得到mid索引为3,递归归并左半部分{6, 202, 100, 301},对这个子序列又中分为{6, 202}和{100, 301},此时这两个子序列已有序;递归归并右半部分{38, 8, 1},对这个子序列又中分为{38, 8}和{1},归并后形成{8,38}和{1},共比较3次

2、第二次归并:第一次归并后变成{6,202},{100,301},{8,38},{1},即{6, 202,100,301,8,38,1},再中分得到{6,202,100,301}和{8,38,1},分别递归归并后为{6,100,202,301}新序列和{1,8,31}新序列,共比较3+1=4次。

3、第三次归并:第二次归并后,得到的两个有序的子序列为{6,100,202,301}和{1,8,38},这一次是递归回到第一层了,已经是中分了,直接比较和复制到新的r即可。最终得到{1,6,8,38,100,202,301},共比较4次(6与1比较,6与8比较,100与8比较,100与38比较)。

这个序列从无序到有序总共比较了3+4+4=11次。

算法复杂度分析

归并排序的效率是比较高的,假设数列长度为N,采用中分法的方式将数列分开成若干个小数列一共要log2N 步,每步都是一个合并有序数列的过程,时间复杂度可以记为O ( N ),故一共为O ( N * log2N)。

因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在常用的几种排序方法(快速排序,归并排序,希尔排序,堆排序)中也是效率比较高的。

时间复杂度:O ( N * log2N )

C语言实现

测试:

打印效果:

从打印结果可以看出来,果然与我们前面的算法分析是一样的。

原文地址:https://www.cnblogs.com/gongyuhonglou/p/10311576.html