动画演示
归并过程Merge
设置一个辅助空间aux(图下二数组)
代码优化,merge操作只在arr[mid] > arr[mid+1]时进行,否则说明两部分是有序的,这样当数组接近有序的情况,归并次数减少,效率提高。
void mergeSort(int[] arr){
mergeSort(arr, 0, arr.length-1);
}
//对arr[l...r]的范围进行排序
void mergeSort(int[] arr, int l, int r){
//代表递归到底只有一个元素,则无需排序
if(l >= r)
return;
int mid = l + (r-l)/2;
mergeSort(arr, l, mid);
mergeSort(arr, mid+1, r);
if(arr[mid] > arr[mid+1]) //代码优化
merge(arr, l, mid, r);
}
//将arr[l...mid]和arr[mid+1...r]两部分进行归并
void merge(int[] arr, int l, int mid, int r){
int[] aux = new int[r-l+1];
for(int i = l; i<=r; i++)
aux[i-l] = arr[i];
int i = l, j = mid+1;
for(int k=l; k<=r; k++){
//边界条件判断
if(i > mid){
arr[k] = aux[j-l];
j++;
}else if(j > r){
arr[k] = aux[i-l];
i++;
}
//正常逻辑
else if(aux[i-l] < aux[j-l]){
arr[k] = aux[i-l];
i++;
}else{
arr[k] = aux[j-l];
j++;
}
}
}
merge代码简化:
private void merge(int[] nums, int l ,int mid, int r){
int[] temp = new int[r-l+1];
for(int i=0; i<temp.length; i++)
temp[i] = nums[l+i];
//m遍历temp[0...mid-l],n遍历temp[mid-l+1...r-l]
int m = 0, n = mid-l+1;
for(int i=l; i<=r; i++){
if(m > mid-l)
nums[i] = temp[n++];
else if(n > r-l)
nums[i] = temp[m++];
else if(temp[m] < temp[n])
nums[i] = temp[m++];
else
nums[i] = temp[n++];
}
}