归并排序(MERGE-SORT)
是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。
C语言代码实现:
#include<stdio.h>
#include<stdlib.h>
#define MAX 20
//归并
void Merge(int arr[],int start,int center,int end){
int i=start;
int j=center+1;
int temp[MAX];
int k=0;//临时数组存放位置
while(i<=center && j<=end){
if(arr[i]<=arr[j])
temp[k++]=arr[i++]; //存入较小元素
else
temp[k++]=arr[j++];
}
if(i == center+1){ //左块先存完,直接加入右块
while(j <= end)
temp[k++]=arr[j++];
}
else{
while(i <= center)
temp[k++]=arr[i++];
}
for(j=0,i=start;j<k;i++,j++) //将已排序的temp存入原数组arr
arr[i] = temp[j];
}
//递归
void Msort(int a[],int start,int end){
if(start<end){ //拆分成两个一对后停止,开始调用Merge归并
int center=(start+end)/2;
Msort(a,start,center); //递归拆分左
Msort(a,center+1,end); //递归拆分右
Merge(a,start,center,end);
}
}
int main(void){
int a[MAX];
int i;
for(i=0;i<MAX;++i)
a[i]=rand()%100; //0~99
printf("排序前:\n");
for(i=0;i<MAX;i++){
if(i%10 == 0) printf("\n");
printf("%4d",a[i]);
}
Msort(a,0,MAX-1);
printf("\n排序后:\n");
for(i=0;i<MAX;i++){
if(i%10 == 0) printf("\n");
printf("%4d",a[i]);
}
getchar();
return 0;
}
递归的改进
在递归的代码中一直递归到数组长度为1为止,之后进行合并操作,实际上,当数组长度较小时可以使用插入排序进行较短数组的排序,不用递归到底
//插入排序
void insertSort(int a[], int start, int end) {
int i,j;
int temp;
for (i = start; i <= end; i++){
temp = a[i]; //待插入元素
for (j = i-1; j >= start && temp < a[j]; j--){
a[j+1]=a[j];
}
a[j+1]=temp;
}
}
if(start-end<=MIN){ //长度界限
insertSort(a,start,end);
return;
}