点击查看代码
#include<cstdio>
#pragma warning(disable:4996)
//二路归并排序从上往下(升序排序)
//2、二路归并排序:归并
void merge(int a[], int n, int start, int mid, int end) {
int* tmp = new int[n];//tmp[]是汇总2个有序数组的临时数组
int k = 0, i = start, j = mid + 1; //k是tmp[]的索引,i和j是第1个和第2个有序数组的索引
//第1个有序数组范围[start,mid],第2个[mid+1,end]
while (i <= mid && j <= end) {
//升序排序,将较小的元素存入tmp[]中
if (a[i] <= a[j]) {
tmp[k++] = a[i++];
}
else {
tmp[k++] = a[j++];
}
}
while (i <= mid) { //因为剩余的元素是有序的,可以直接存入tmp[]中
tmp[k++] = a[i++];
}
while (j <= end) {
tmp[k++] = a[j++];
}
//将tmp[]中排好序的元素复制回a[]中
for (i = 0; i < k; i++) {
//a[i] = tmp[i]; //要以start为起点复制元素,否则排序错误
a[start + i] = tmp[i];
}
delete[] tmp; //释放new创建的tmp[]内存
}
//1、二路归并排序:分解,对a[]在[start,end]范围内进行两两分解
void merge_sort(int a[], int n, int start, int end) {
//递归退出条件:左边界超出右边界或数组为空
if (start < end && a != NULL) {
int mid = start + ((end - start) >> 1); //求中点mid
//先分解
merge_sort(a, n, start, mid); //以中点为分界线,对左半部分[start,mid]进行分解
merge_sort(a, n, mid + 1, end); //以中点为分界线,对右半部分[mid+1,right]进行分解
//后归并
merge(a, n, start, mid, end); //分解到序列只有一个元素时才进行归并
}
}
int main() {
int a[] = { 80,70,40,30,60,50,20,10 };
int n = (sizeof(a)) / (sizeof(a[0]));
printf("序列个数:%d\n", n);
printf("排序前:");
for (int i = 0; i < n; i++) {
printf("%d", a[i]);
if (i < n - 1) printf(" ");
else printf("\n");
}
merge_sort(a, n, 0, n - 1); //对a[]进行归并排序,n个元素,初始区间[0,n-1]
printf("排序后:");
for (int i = 0; i < n; i++) {
printf("%d", a[i]);
if (i < n - 1) printf(" ");
else printf("\n");
}
return 0;
}