归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并过程为:比较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]。
以上内容摘自360百科,下面举一个例子表达我对归并的理解。
一个数列:{13, 27, 19, 8, 12, 2, 30, 89}
第一次排序:{13 ,27} ,{19 , 8}, {12 , 2}, {30 ,89}
排序后 {13,27} ,{8, 19},{2,12},{30,89}
13,27,8,19,2,12,30,89
第二次排序:{13,27,8,19} ,{2,12,30,89}
排序后:{8,19,13,27},{2,12,30,89}
8 , 9, 13,27,2,12,30,89
第三次排序:{8 , 9, 13,27,2,12,30,89}
排序后:2,8,9,12,13,27,30,89
代码:
#include <stdio.h>
int Merge(int a[],int s,int m,int e,int tem[]) //对数组a 区间 a[s] 到 a[e] 排序
{
int p1 = s, p2 = m+1;
int pb = 0;
while(p1 <= m && p2 <= e)
{
if(a[p1] < a[p2])
tem[pb++] = a[p1++];
else
tem[pb++] = a[p2++];
}
while(p1 <= m)
{
tem[pb++] = a[p1++];
}
while(p2 <= e)
{
tem[pb++] = a[p2++];
}
for(int i=0; i<e-s+1; i++)
a[s+i] = tem[i];
}
int Mergesort(int a[],int s,int e,int tmp[])
{
if(s < e)
{
int m = s+ (e-s)/2;
Mergesort(a,s,m,tmp); //对左区间归并
Mergesort(a,m+1,e,tmp); // 对右区间归并
Merge(a,s,m,e,tmp); //对数组a 区间 a[s] 到 a[e] 排序
}
}
int a[8] = {13, 27, 19, 12, 2, 8, 30, 89}; // 样例数列
int b[10]; // 中间变量数组,无实际意义。
int main()
{
int size = sizeof(a)/sizeof(int);
Mergesort(a,0,size-1,b); // 对 a[] 归并排序
for(int i=0; i<size; ++i)
printf("%d ,",a[i]); // 输出数组 a
return 0;
}