二路归并排序从上往下

点击查看代码
#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;
}

posted @ 2022-09-26 21:52  zhaoo_o  阅读(5)  评论(0编辑  收藏  举报