排序算法之归并排序

你离开我真会死。 提交于 2019-12-28 23:36:43

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

#include <iostream>

using namespace std;

//归并算法

/**
一句箴言:将待排序数据一分为二,二分为四,四分为八,递归下去,直至每份为1个元素,这一个元素自身一定为有序的,然后再将分了的两两合并为有序数组,最终变成一个有序数组。

方法:递归拆分并两两合并为有序数组。其中合并时候需要将待合并的两组数据拷贝出来,指定左待归并数据索引i,右待归并数据索引j, k为原数组需重新指定值得索引

**/


void _merge(int arr[], int l, int mid, int r) {

	//归并前判断是否分割的两数组已经左边小右边大了
	if (arr[mid+1] > arr[mid]) {
		return;
	}

	//首先需要拷贝出待归并区间的数据 区间为索引l到 r
	int aux[r - l + 1];
	for (int i = l ; i <= r; i++) {
		aux[i - l] = arr[i];
	}

	/**
		// 注释的是去除掉偏移量l后的数组 求解法
		int max = r -l;
		int newMid = (max - min) / 2;
		int i = 0,j = newMid + 1;
		//遍历原数组l到 r 这个区间,走待归并的两个区间里选择最小的去填充覆盖
		for (int k = l; k <= r; k++) {
			//当左边的都已经赋值完,索引已经越过中间点,则只剩下右边的了
			if (i > newMid ) {
				arr[k] = aux[j];
				j++;
			} else if (j > max) {
				arr[k] = aux[i];
				i++;
			} else if(aux[i] < aux[j]) {
				arr[k] = aux[i];
				i++;
			} else {
				arr[k] = aux[j];
				j++;
			}
		}
		**/

	int i = l,j = mid + 1;
	//遍历原数组l到 r 这个区间,走待归并的两个区间里选择最小的去填充覆盖
	for (int k = l; k <= r; k++) {
		//当左边的都已经赋值完,索引已经越过中间点,则只剩下右边的了
		if (i > mid ) {
			arr[k] = aux[j-l];
			j++;
		} else if (j > r) {
			arr[k] = aux[i-l];
			i++;
		} else if(aux[i-l] < aux[j-l]) {
			arr[k] = aux[i-l];
			i++;
		} else {
			arr[k] = aux[j-l];
			j++;
		}
	}

}

void mergeSort(int arr[], int l, int r) {

	//递归则首先要找到跳出条件
	if (l >= r) {
		return ;
	}

	//一分为二,递归调用自己排序
	int mid = (r + l) / 2;
	mergeSort(arr, l, mid);
	mergeSort(arr, mid+1, r);

	//归并
	_merge(arr, l, mid, r);

}


int main() {

	int arr[10] = {10,9,8,7,6,5,4,3,2,1};

	mergeSort(arr, 0,  9);

	for(int i =0; i< 10; i++) {
		cout << arr[i] << "  ";
	}

	return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!