java代码之归并排序

版权声明:https://me.csdn.net/qq_42079455 https://blog.csdn.net/qq_42079455/article/details/88599465

1、归并排序的基本思想
归并排序的核心是采用分治法,即将一个长度为n的待排序列,分成n个长度为1的序列,(这n个长度为1的序列可以看成n个有序序列),然后两两归并,得到n/2个新的有序序列,在两两归并,如此重复,直到得到一个长度为n的有序序列位置(两两归并的过程也可以叫做二路归并)
2、归并排序图解
分而治之,先分后治:
分的过程:将一个长度为n的待排序列,分成n个长度为1的序列,这n个长度为1的序列可以看成n个有序序列
在这里插入图片描述

治的过程:将这n个有序序列两两归并,得到n/2个新的有序序列,在两两归并,如此重复,直到得到一个长度为n的有序序列位置
在这里插入图片描述
3、归并排序代码

package sort_suanfa;

public class Merge_Sort {
	public static void main(String[] args) {
		Merge_Sort mergeSort = new Merge_Sort();
		int[] a = new int[] { 49, 38, 65, 97, 76, 13, 27 };
		mergeSort.mergeSort(a, 0, a.length - 1);
		for (int n : a) {
			System.out.print(" " + n);
		}
	}

	public void mergeSort(int[] a, int left, int right) {
		if (left < right) {
			// 将长度为n的待排序列,分成n个长度为1的有序序列
			int middle = (left + right) / 2;
			mergeSort(a, left, middle);
			mergeSort(a, middle + 1, right);
			// 二路归并
			merge(a, left, middle, right);
		}
	}

	public void merge(int[] array, int left, int middle, int right) {
		int[] tmpArray = new int[array.length];
		int rightStart = middle + 1;
		int tmp = left;
		int curIndex = left;// 用来表示当前下标++
		// 比较两个小数组相应下标位置的数组大小,小的先放进新数组
		while (left <= middle && rightStart <= right) {
			if (array[left] <= array[rightStart]) {
				tmpArray[curIndex++] = array[left++];
			} else {
				tmpArray[curIndex++] = array[rightStart++];
			}
		}
		// 如果左边还有数据需要拷贝,把左边数组剩下的拷贝到新数组
		while (left <= middle) {
			tmpArray[curIndex++] = array[left++];
		}
		// 如果右边还有数据需要拷贝,把右边数组剩下的拷贝到新数组
		while (rightStart <= right) {
			tmpArray[curIndex++] = array[rightStart++];
		}
		// 将数据拷贝到原来的数组中
		while (tmp <= right) {
			array[tmp] = tmpArray[tmp++];
		}
	}
}

运行结果:
在这里插入图片描述
4、归并排序性能分析
时间复杂度
该算法的最优时间复杂度和最差时间复杂度以及平均复杂度是一致的:O(nlogn)
空间复杂度
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)
算法稳定性
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法
其他:
若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。
若从稳定性来考虑,选择归并排序,堆排序和快速排序都不稳定。
若从平均情况下的排序速度考虑,应该选择快速排序。

猜你喜欢

转载自blog.csdn.net/qq_42079455/article/details/88599465