常见排序算法之归并排序详解JAVA实现

1.归并排序简介

_ 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,
再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并排序是一种稳定的排序方法。_

简而言之:
== 1. 把数组拆分
2. 然后把数组合并,在合并的过程中排序==

归并排序运用的分治的思想,优势体现在此,把一个长的数组(长度为n)排序拆分为若干个小数组排序,小数两两组合并后,数组总数变成了n / 2 , 把合并后的数组内部排序,再合并,再排序…直到合并成为长度为n的数组。

拆分过程

在这里插入图片描述
合并排序过程
到了这里长数组已经被拆分为n个长度为 1 的 小数组。
在这里插入图片描述在这里插入图片描述在这里插入图片描述如何实现合并排序

归并排序中相对重要的就是合并排序的时候所用的方法,即两个有序数组的排序。我们就拿上图合并到的最后数组举例。
在这里插入图片描述
先设置两个数组的开始点,左边third 右边rightStart。在创建一个和原数组一样大大小的数组tmpArray[],我们要把比较后小的数存放到这个数组中。
两个数组都是有序的,比较third 和 rightStart 位置上的数,2 < 3, rightStart 自加1 ,把2存入 tmpArray , 再次比较third 和 rightStart 位置上的数,3 < 10,third 自加1,把3存入tmpArray…
当third大于middle,或者rightStar大于right时停止比较。
比较停止后有两种情况
1.third到头了,但是rightStar没到头(抵达middle)。因为两个数组都是有序的,我们只需要把rightStar后面的数全部移动到 tmpArray 后面即可。
2.rightStar到头了,但是third没到头,我们把third后面(middle之前)的数直接移动tmpArray 后面即可。

2.代码实现

public class MergeSort {
	
	/**
	 * 核心方法
	 */
	public void mergeSort(int [] a,int left,int right) {
		if (left < right) {
			int middle = (left + right)/2;
			mergeSort(a, left, middle);
			//这里有个小错误哦
			mergeSort(a, middle + 1, right);
			merge(a,left,middle,right);
		}
		
	}
	
	/**
	 * 合并数组
	 */
	
	public void merge(int []a,int left,int middle,int right) {
		//需要一个新的数组在存
		int [] tmpArray = new int [a.length];
		int rightStart = middle+1;
		int third = left;
		int tmp = left;
		
		//还用if啊 用while
		while(left <= middle && rightStart <= right) {
			if (a[left] <= a[rightStart]) {
				tmpArray[third ++] = a[left++];
			}else {
				tmpArray[third ++] = a[rightStart++];
			}
		}
		while(left<=middle){
			tmpArray[third++] = a[left++];
		}
		//如果右边还有数据......
		while(rightStart<=right){
			tmpArray[third++] = a[rightStart++];
		}
		while(tmp<=right){
			a[tmp] = tmpArray[tmp++];
		}	
	  
	}

3.法优缺点

优点:
一, 归并排序的效率达到了巅峰:时间复杂度为O(nlogn),这是基于比较的排序算法所能达到的最高境界

二, 归并排序是一种稳定的算法(即在排序过程中大小相同的元素能够保持排序前的顺序,3212升序排序结果是1223,排序前后两个2的顺序不变),这一点在某些场景下至关重要

三, 归并排序是最常用的外部排序方法(当待排序的记录放在外存上,内存装不下全部数据时,归并排序仍然适用,当然归并排序同样适用于内部排序…)

缺点:
归并排序需要O(n)的辅助空间,而与之效率相同的快排和堆排分别需要O(logn)和O(1)的辅助空间,在同类算法中归并排序的空间复杂度略高

猜你喜欢

转载自blog.csdn.net/qq_43507104/article/details/104903457
今日推荐