归并排序(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];
}
}
}