【代码注释详细】Java实现归并排序算法

1、概述

      归并排序是一种稳定的算法,该算法采用分治法的典型的应用。将已有自序列合并,得到完全有序的序列。即先使每个子序列有序,再使子序列之间有序。然后将两个有序表合成一个有序表,称为二路归并。

     归并操作,也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。

     如 设有数列{6,202,100,301,38,8,1}

    初始状态:6,202,100,301,38,8,1

    第一次归并后:{6,202},{100,301},{8,38},{1}

    第二次归并后:{6,100,202,301},{1,8,38}

    第三次归并后:{1,6,8,38,100,202,301}

2、归并排序算法思路分析

     ①  申请一个和原数组一样的空间存储排序好的数组

     ②  定义两个指针,初识位置为两个排好序的起始位置

     ③  比较两个指针所指向的元素,选择比较小的放到新的数组空间,往下移动指针

    重复步骤③,直到将剩下的数组添加到新数组的结尾

    比如初始数组:[24,13,26,1,2,27,38,15]

    ①分成了两个大小相等的子数组:[24,13,26,1]    [2,27,38,15]

    ②再划分成了四个大小相等的子数组:[24,13]   [26,1]    [2,27]    [38,15]

    ③此时,left < right 还是成立,再分:[24]   [13]   [26]    [1]    [2]     [27]    [38]   [15]

    此时,有8个小数组,每个数组都可以视为有序的数组了!!!,每个数组中的left == right,从递归中返回

        // 将数组元素分开
        mergeSort(arr,left,mid);
        mergeSort(arr,mid+1,right);
        // 将数组元素比较 排序合并
        merge(arr,left,mid,right);

       然后——>

       merge([24],[13]) 得到 [13,24]

       merge([26],[1]) 得到[1,26]

3、代码实现

public class MergeDemo {
	
	public static void main(String[] args) {
		int[] array = {7,3,1,4,8,10};
		mergeSort(array, 0, 5);
		merge(array, 0, 2, 5);
		System.out.println(Arrays.toString(array));
	}
	
	// 一 对整个数组进行排序
	// 先对整个序列进行分组
	// 参数 需要排序的数组  数组的第一个位置  数组的最后一个位置 将排序的数组放在新的数组里面
	private static void mergeSort(int[] arr,int left,int right) {
		// 判断数组
		if(left >= right) {
			return;
		}
		// 分治左边和右边  取中间坐标
		int mid = (left + right)/2;
		// 将数组元素分开
		mergeSort(arr,left,mid);
		mergeSort(arr,mid+1,right);
		// 将数组元素比较 排序合并
		merge(arr,left,mid,right);
	}
	
	// 合并
	private static void merge(int[] arr,int left,int mid,int right) {
		// 定义第一个归并序列开始的地方
		int s1 = left;
		
		// 定义第二个归并序列开始的地方
		int s2 = mid + 1;
		
		// 定义已经归并好的序列元素存放的位子
		int[] temp = new int[arr.length];
		//定义临时序列的下标 从0开始
		int i = 0;
		// 向临时序列赋值
		while(s1 <= mid && s2 <= right) {
			if(arr[s1] <= arr[s2]) {
				temp[i++] = arr[s1++];
			}else {
				temp[i++] = arr[s2++];
			}
		}
		
		// 如果其中一个序列比较完了 剩下的那组序列就放进去
		while(s1 <= mid) {
			temp[i++] = arr[s1++];
		}
		while(s2 <= right) {
			temp[i++] = arr[s2++];
		}
		// 将temp中的元素 复制到 arr序列中
		i = 0;
		while(left <= right) {
			arr[left++] = temp[i++];
		}
	}
}

4、算法复杂度分析

    归并排序的时间复杂度为O(nlogn),具体的计算请访问:https://blog.csdn.net/a1033025319/article/details/88650514

   归并排序是所有排序中比较次数最少的,它一开始不断的划分,比较只发生在合并的各个有序的子数组中。

5、总结

   归并排序递归方式比较难理解的就是排序合并。一开始比较迷茫,分开的各部分数组怎么排序的呢?是调用这行代码:merge(arr,left,mid,right)。把各个元素合并的时候进行排序。

   OK,今天就到这里,喜欢的话点个赞。

猜你喜欢

转载自blog.csdn.net/Sunshineoe/article/details/114747590