不断分成左右两个区间,当每个区间只剩一个元素时不再分了,开始合并。
合并时,比较两个区间的元素(双指针),谁小,暂存数组存谁,同时移动指针,直到一个数组的元素已经存完,将另一个数组剩下的元素存入暂存数组。
用一个暂存数组,存储不断合并后的结果,将合并的最终结果赋给原数组。
不断递归划分左右区间,之后再合并,有点类似于二叉树的后序遍历。
public class MergeSort {
public static void main(String[] args) {
int[] a = {4, 6, 2, 1, 7, 9, 5, 8, 3};
int[] temp = new int[a.length];
mergeSort(a, 0, a.length - 1, temp);
System.out.println(Arrays.toString(a));
}
public static void mergeSort(int[] array, int start, int end, int[] temp){
if(start >= end) return;
mergeSort(array, start, (start + end) >> 1, temp);
mergeSort(array, ((start + end) >> 1 ) + 1, end, temp);// >>的优先级小于+号
//合并
merge(array, start, end, temp);
}
public static void merge(int[] array, int start, int end, int[] temp){
//左区间左端和右端
int left = start;
int middle = (start + end) >> 1;
//右区间左端
int right = middle + 1;
//暂存数组起点下标
int index = left;
while(left <= middle && right <= end){
if(array[left] < array[right]){
temp[index++] = array[left++];
}else {
temp[index++] = array[right++];
}
}
//某个区间剩余的数据
while(left <= middle) temp[index++] = array[left++];
while(right <= end) temp[index++] = array[right++];
for(int i = start; i <= end; i++){
array[i] = temp[i];
}
}
}