将两个有序表合并成一个有序表的过程称为2路归并;
区别于前几种排序方法,这个排序方法是用递归实现,其中体现了分治的思想。
归并排序思想:假设初始序列含有n个记录(元素),则可以看作是n个有序的子序列,其中每个序列的长度为1,然后两两归并。得到n/2个长度为2的有序子序列;然后再两两归并,形成n/4个子序列……重复执行(递归,终止条件为形成1个子序列),直到得到一个长度为n的有序序列。即排序完成。
将两个有序序列合成一个有序序列的过程:
假设有两个有序X,Y序列,放在同一个顺序表a[low,high]当中,其中一个在a[low,mid]中,另一个在[mid+1,high]中,每次从两个表中取出一个元素进行比较,将较小的一个存入一个顺序表B[low,high]中,重复这个过程,直到两个有序表中其中一个为空,然后将不为空的那一个按顺序复制到B中。
C代码实现:
void Merge (int a[],int low,int mid,int high){
int i,p,l,h;//定义下表p,用于B[] 下标l,h分别指向剩余部分的头,和尾
int *B=(int*)malloc((high-low+1)*sizeof(int));//动态申请一个临时数组B[]
int k1_low=low,k1_high=mid;
int k2_low=mid+1,k2_high=high;
for(p=0;k1_low<=k1_high&&k2_low<=k2_high;p++){//每次从K1,K2中取出一个元素进行比较,将较小的存入B[]
if(a[k1_low]<=a[k2_low])
B[p]=a[k1_low++];
else
B[p]=a[k2_low++];
}
if(k1_low>k1_high){//当k1_low>k1_high时,证明k1先结束
l=k2_low;
h=k2_high;
}
else if(k2_low>k2_high){//相反则证明k2先结束
l=k1_low;
h=k1_high;
}
while(l<=h){//将剩余的部分复制到B[]中
B[p++]=a[l++];
}
for(i=0;i<high-low+1;i++){//将重新组合的部分重新拷入原数组的同一个地方
a[low+i]=B[i];
}
for(i=0;i<N;i++){
printf("%d\t",a[i]);
}
printf("\n");
free(B);//释放动态申请的空间
return;
}
归并排序算法描述:将一个无序表a[low,high]进行归并排序,并存入B[low,high]。
1>将当前序列一分为2,并求出分裂点mid=(low+high)/2,并向下取整。 2>对于a[low,mid]递归,进行归并排序,并存入中间顺序表K1 3>对于a[low,high]进行递归,进行归并排序,并存入中间顺序表K2 4>对于生成的K1,K2这两个有序表进行合并。将新生成的有序表返回。
整体C语言描述:
#include <stdio.h> //需要使用基本输入输出函数
#include <stdlib.h> //需要使用malloc(),free() 函数
//归并排序
#define N 10
void Merge (int a[],int low,int mid,int high){
int i,p,l,h;//定义下表p,用于B[] 下标l,h分别指向剩余部分的头,和尾
int *B=(int*)malloc((high-low+1)*sizeof(int));//动态申请一个临时数组B[]
int k1_low=low,k1_high=mid;
int k2_low=mid+1,k2_high=high;
for(p=0;k1_low<=k1_high&&k2_low<=k2_high;p++){//每次从K1,K2中取出一个元素进行比较,将较小的存入B[]
if(a[k1_low]<=a[k2_low])
B[p]=a[k1_low++];
else
B[p]=a[k2_low++];
}
if(k1_low>k1_high){//当k1_low>k1_high时,证明k1先结束
l=k2_low;
h=k2_high;
}
else if(k2_low>k2_high){//相反则证明k2先结束
l=k1_low;
h=k1_high;
}
while(l<=h){//将剩余的部分复制到B[]中
B[p++]=a[l++];
}
for(i=0;i<high-low+1;i++){//将重新组合的部分重新拷入原数组的同一个地方
a[low+i]=B[i];
}
printf("\n");
free(B);//释放动态申请的空间
return;
}
void MSort(int a[],int low,int high){
int mid=0;
if(low<high){
mid=(low+high)/2;
MSort(a,low,mid);
MSort(a,mid+1,high);
Merge(a,low,mid,high);
}
return;
}
int main (void){
int i;
int a[N]={9,2,6,3,5,1,7,8,4,0};
for(i=0;i<N;i++){
printf("%d\t",a[i]);
}
printf("\n");
MSort(a,0,9);
for(i=0;i<N;i++){
printf("%d\t",a[i]);
}
}
运行结果: