归并排序其实就是分治思想的应用。分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
如下图:对数组进行排序,先按二分法拆分数组,然后依次对每一个单元进行拆分。直到拆分到单个元素。
代码如下:
public class Test_ArraySort {
public static void main(String[] args) {
int[] arr = new int[] {8, 7, 3, 10, 9, 6, 12, 2, 5};
System.out.println(Arrays.toString(arr));
int[] aa = MergeSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(aa));
}
public static int[] MergeSort(int[] arr, int low, int high) {
if(arr == null || arr.length == 0 || high < low)
return null;
//数组中位数
int mid = (low + high)/2;
if(low < high) {
//分治低位到中间位的数
MergeSort(arr, low, mid);
//分治中位到高位的数
MergeSort(arr, mid+1, high);
Merge(arr, low, mid, high);
}
return arr;
}
private static void Merge(int[] arr, int low, int mid, int high) {
//定义一个中间数组,把对应的部分输入数组中
int[] temp = new int[high-low + 1];
//定义两个指针,分别指向两个分治的子单元
int i = low, j = mid+1;
//temp下标从零开始
int k = 0;
//把两个子单元按照从小到大的顺序排序
while(i <= mid && j <= high) {
if(arr[i] <= arr[j]) {
temp[k++] = arr[i++];
}else {
temp[k++] = arr[j++];
}
}
//low-mid中剩余的进数组中
while(i <= mid) {
temp[k++] = arr[i++];
}
//mid+1-high中剩余的进数组中
while(j <= high) {
temp[k++] = arr[j++];
}
//将temp中数组元素覆盖到arr指定的位置
for(int x = 0; x < temp.length; x++) {
arr[low + x] = temp[x];
}
//System.out.println(Arrays.toString(arr));
}
}