归并排序——思路及其实现

       归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

       归并排序中,我们会先找到一个数组的中间下标mid,然后以这个mid为中心,对两边分别进行排序,之后我们再根据两边已排好序的子数组,重新进行值大小分配。

我们就以下面的数组为例

         

     (1)mid等于数组最大下标 / 2 = 3,于是我们以下标3(值为7)为中心,分别排序0~3和4~7的数字。

     (2)此时两边的数组还可以创建分支:

                                       

       (3)可以看到上面还有四个小数组,我们继续创建分支:

                           

     (4)可以看到,此时我们已经无法继续创建分支了,因为数组数量为1时是没有必要进行排序的,这时我们可以开始进行对每一个小的数组进行排序并且合并:

                               

     (5)继续,拿到上一步组成的小数组,再组合成新的排序数组:

                                   

     (6)最后,我们想要的结果就来了:

                   

代码如下:

public class MergeSort {
	public static void mergeSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		mergeSort(arr, 0, arr.length - 1);
	}

	public static void mergeSort(int[] arr, int l, int r) {
		if (l == r) {
			return;
		}
		int mid = l + ((r - l) >> 1);
		mergeSort(arr, l, mid);
		mergeSort(arr, mid + 1, r);
		merge(arr, l, mid, r);
	}

	public static void merge(int[] arr, int l, int m, int r) {
		int[] help = new int[r - l + 1];
		int i = 0;
		int l1 = l;
		int r1 = m + 1;
		while (l1 <= m && r1 <= r) {
			help[i++] = arr[l1] < arr[r1] ? arr[l1++] : arr[r1++];
		}
		while (l1 <= m) {
			help[i++] = arr[l1++];
		}
		while (r1 <= r) {
			help[i++] = arr[r1++];
		}
		for (int j = 0; j < help.length; j++) {
			arr[l + j] = help[j];
		}
	}
}

  

posted @ 2018-05-01 23:30  Booker808  阅读(1272)  评论(0编辑  收藏  举报