一、基本思想
归并排序,就是利用归并思想实现的排序方法。它的原理是:假设初始序列含有 n 个记录,则可以看成 n 个有序的子序列,每个子序列的长度为 1,然后两两归并,得到 n 2 \frac{n}{2} 2n 个长度为 2 或 1的有序子序列;再两两归并,…,如此重复,直至得到一个长度为 n 的有序序列为止,这种排序方法也称 2 路归并排序。
这个过程就是经典的分治法(divide-and-conquer):分阶段(divide) 先将原问题分成若干小问题进行求解;治阶段(conquer) 则将分阶段得到的答案合并在一起,得到整个问题的解。图示如下:
二、代码实现
public static int[] mergeSort(int[] array){
if(array.length < 2)
return array;
// 分(divide)
int mid = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, mid);
int[] right = Arrays.copyOfRange(array, mid, array.length);
// 治(conquer)
return merge(mergeSort(left), mergeSort(right));
}
// 归并(治)
public static int[] merge(int[] left, int[] right){
int[] res = new int[left.length + right.length];
int l = 0;
int r = 0;
int i = 0;
// 两个数组都不为空,比较第一个元素的大小,小的放到 res
while(l < left.length && r < right.length){
if(left[l] <= right[r]){
res[i++] = left[l++];
}else{
res[i++] = right[r++];
}
}
// 有一个数组已经合并完了,把另一个数组剩下的元素放入 res
while(l < left.length){
res[i++] = left[l++];
}
while(r < right.length){
res[i++] = right[r++];
}
return res;
}
Tips:
归并排序其实相当于合并 n 个有序数组。可以扩展一下 leetcode 88.合并两个有序数组