/*归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,
即把待排序序列分为若干个子序列,每个子序列是有序的。
然后再把有序子序列合并为整体有序序列。*/
# include<stdio.h> //时间复杂度 O(nlogn) 稳定
//合并两个已经排好顺序的数组
void Merge(int a[], int start, int mid, int end, int *temp){
int i = start, j = mid+1, k = 0;//start到mid位数组1,mid+1到end为数组2
while(i<=mid && j<=end) //从两个数组最低位开始比较,数值小的存入临时数组
temp[k++] = (a[i] <= a[j]) ? a[i++] : a[j++];
while(i <= mid) //总有一个数组先比较完,所以处理剩下数组的元素
temp[k++] = a[i++];
while(j <= end)
temp[k++] = a[j++];
k = 0; //下面将排完序的临时数组里的数拷贝到原数组里
for(i = start; i <= end; i++)
a[i] = temp[k++];
}
//用分治法进行二路归并
void MergeSort(int a[], int start, int end, int *temp){
if(start < end){ //当数组至少有两个元素时,进行二路归并
int mid = (start+end)/2;
MergeSort(a, start, mid, temp);
MergeSort(a, mid+1, end, temp);
Merge(a, start, mid, end, temp);
}
}
int main(){
int n;
printf("请输入你要排序的数的个数:");
scanf("%d", &n);
int temp[n] = {-1}; //临时数组,作为参数传递,避免每次在merge中分配临时数组
int *a = new int[n+1]; //申请一个整型变量空间,没有赋初值,并定义一个整型指针a指向该地址空间
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
MergeSort(a, 1, n, temp);
printf("排序后:");
for(int j = 1; j <= n; j++)
printf("%6d", a[j]);
delete []a;//回收数组a的空间
return 0;
}