归并排序(Merge Sort)是利用“归并”技术来进行排序,所谓归并是指将若干个子文件合并为一个文件的过程,由约翰·冯·诺伊曼发明。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。即是将文件先分解再合并,最终得到有序序列。
给出一组数据,根据由小到大顺序输出。
输入一个整数n(数据长度)
输入n个数据
输出由小到大排序后的数据
10
37 28 46 19 55 28 92 84 63 71
19 28 28 37 46 55 63 71 84 92
假设待排序的数据都存放在数组R[n]中,mid是数组长度的一半,将数组分成R[0] ~ R[mid]和R[mid+1] ~ R[n-1]两个子文件,用递归的方式继续将这两个子文件再各自分解成两部分,直至子文件中只有1个元素,这是分解的过程。然后将两个子文件合并成一个有序文件,直至形成有序序列,这是归并的过程。
分解的过程利用递归操作即可实现。而排序的重点是归并的过程,即如何将两个文件合并成一个有序序列。以本例最后一次归并过程为例(经过前几次归并后,这两个子文件自身都是有序的),i 和 j 分别指向两个子文件的第一个元素,并定义一个临时数组Temp,i 和 j 位置元素进行比较,将较小的放入临时数组,然后向右继续比较。
当一个子文件内所有元素都已放入临时数组Temp中,另一个子文件剩余元素无需再比较,因为经过前面的归并子文件本身是有序的,直接依次放入临时数组中即可。
#include
void merge_sort(int R[],int start,int end); //归并排序
void merge(int R[],int start,int mid,int end); //归并过程
int main()
{
int i,R[100],n;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&R[i]);
merge_sort(R,0,n-1);
for(i=0;i<n;i++)
printf("%d ",R[i]);
return 0;
}
void merge(int R[],int start,int mid,int end)
{
int Temp[end-start+1]; //定义临时数组
int i=start; //i 和 j 分别指向两个子文件的第一个元素
int j=mid+1;
int k=0;
while(i<=mid&&j<=end)
{
if(R[i]<=R[j]) //i 和 j 位置元素进行比较,将较小的放入临时数组
Temp[k++]=R[i++];
else
Temp[k++]=R[j++];
}
while(j<=end) //第一个文件元素都已放入临时数组
Temp[k++]=R[j++]; //将第二个文件剩余元素放入临时数组
while(i<=mid) //第二个文件元素都已放入临时数组
Temp[k++]=R[i++]; //将第一个文件剩余元素放入临时数组
for(i=0;i<k;i++)
R[start+i]=Temp[i]; //将临时数组的元素放回原数组R中
}
void merge_sort(int R[],int start,int end)
{
if(start<end)
{
int mid=(start+end)/2;
merge_sort(R,start,mid); //利用递归实现分解过程
merge_sort(R,mid+1,end);
merge(R,start,mid,end);
}
}
归并排序和快速排序都是分治思想应用在排序中的经典实例,所谓分治即“分而治之”,就是将一个大问题分解成若干小问题,并且小问题要具有和大问题一样的性质,然后将小问题的解合并得到大问题的解。本例中每次归并操作都是将两个子文件合并成一个有序文件,这种方法称为“二路归并排序”。类似地也可以有“三路归并排序”或“多路归并排序”。
利用了分治思想,所以归并排序的效率也是比较高的,利用递归需进行( l o g 2 n log_2n log2n)趟归并,每趟归并花费时间是O( n n n),所以归并排序最好和最坏情况下的时间复杂度均是O( n l o g 2 n nlog _2n nlog2n)。
平均时间复杂度O( n l o g 2 n nlog _2n nlog2n)
空间复杂度O( n n n)
二路归并排序是稳定的。
代码的表达形式多种多样,重点是理解排序的思想和过程,附上一个网上看到的动画,可以帮助理解排序过程☛添加链接描述(个人觉得如果有一些基础的看本文上面给的图示去理解最好,更有助于建立编程的思维,视频能相对有些趣味性)
说明: 链接内视频不是本人制作,如侵权则删。当然网上的视频有很多,我只是找了一个相对简单明了的,大家也可自行搜索。
参考资料:《数据结构-用C语言描述》高等教育出版社
(只是分享个人学习时的想法和理解,如有问题还望大佬指点)