利用归并排序法对序列排序的示意图(递归法):
一、算法分析:利用递归的分治方法:1、将原序列细分,直到成为单个元素;2、在将分割后的序列一层一层地按顺序合并,完成排序。细分通过不断深入递归完成,合并通过递归 一层层返回完成。
二、C语言代码
1、完成排序的三个函数
void MergeSort(int l[],int lenght) { int tmp[lenght]; MSort(l,tmp,1,lenght); } /*分:MSort将原来的序列不断细分,直到为1,再由Merge归并*/ void MSort(int l[],int tmp[],int left,int right) { int mid; if(left!=right) { mid=(left+right)/2; //将待排序序列分成两部分 MSort(l,tmp,left,mid); //将左边排序 MSort(l,tmp,mid+1,right); //将右边排序 Merge(l,tmp,left,mid,right); //将已排序的两部分合并 } } /*数组tmp只是作为临时存储,归并后,再将有序的数组拷贝到原来的l中*/ void Merge(int l[],int tmp[],int left,int mid,int right) { int i,j,t; for(i=left,j=mid+1,t=left;i<=mid&&j<=right;t++) { if(l[i]<=l[j]) { tmp[t]=l[i]; i++; } else { tmp[t]=l[j]; j++; } } /*归并的两个序列不一样长时,将剩余的元素加入tmp*/ if(i<=mid) { for(;i<=mid;i++) { tmp[t]=l[i]; t++; } } if(j<=right) { for(;j<=right;j++) { tmp[t]=l[j]; t++; } } /*将归并后的有序序列拷贝到原数组*/ for(t=left;t<=right;t++) { l[t]=tmp[t]; } }
使用时,调用MergeSort函数就行了
下面是我写的一个测试代码
#include<stdio.h> #include<stdlib.h> #include<time.h> #define NUM 5000 void MergeSort(int l[],int length); void MSort(int l[],int tmp[],int left,int right); void Merge(int l[],int tmp[],int left,int mid,int right); int main() { int i,a[NUM+1]; srand((unsigned)time(NULL)); /*a[0]作为哨兵单元,不在随机数生成之列*/ for(i=1;i<=NUM;i++) { a[i]=rand(); } /*printf("Befor sort:"); for(i=1;i<=NUM;i++) { printf("%d ",a[i]); }*/ MergeSort(a,NUM); printf(" After sort:"); for(i=1;i<=NUM;i++) { printf("%d ",a[i]); } return 0; } void MergeSort(int l[],int lenght) { int tmp[lenght]; MSort(l,tmp,1,lenght); } /*分:MSort将原来的序列不断细分,直到为1,再由Merge归并*/ void MSort(int l[],int tmp[],int left,int right) { int mid; if(left!=right) { mid=(left+right)/2; //将待排序序列分成两部分 MSort(l,tmp,left,mid); //将左边排序 MSort(l,tmp,mid+1,right); //将右边排序 Merge(l,tmp,left,mid,right); //将已排序的两部分合并 } } /*数组tmp只是作为临时存储,归并后,再将有序的数组拷贝到原来的l中*/ void Merge(int l[],int tmp[],int left,int mid,int right) { int i,j,t; for(i=left,j=mid+1,t=left;i<=mid&&j<=right;t++) { if(l[i]<=l[j]) { tmp[t]=l[i]; i++; } else { tmp[t]=l[j]; j++; } } /*归并的两个序列不一样长时,将剩余的元素加入tmp*/ if(i<=mid) { for(;i<=mid;i++) { tmp[t]=l[i]; t++; } } if(j<=right) { for(;j<=right;j++) { tmp[t]=l[j]; t++; } } /*将归并后的有序序列拷贝到原数组*/ for(t=left;t<=right;t++) { l[t]=tmp[t]; } }