本文参考左程云视频讲解,加上自己能够理解的语言的总结以方便自己以后可以做有效复习
左神哔哩哔哩算法视频链接:
package Sort;
/**归并排序步骤:
* 将一个数组归并有序,那就直接设置一个方法可以有序
* 在有序方法里调用将数组一分为二,递归自己使左右数组有序
* 在有序方法的最后使用归并方法把已经有序数组的进行最终排序
*
* 时间复杂度:O(nlogn) 是稳定算法,无论好坏都是O(nlogn)
* 空间复杂度:O(n)
*/
public class MergeSort {
public static int[] MergeSort(int[] arr){
if (arr == null || arr.length < 2){
return arr;
}
//调用数组有序方法
return process(arr,0,arr.length-1);
}
public static int[] process(int[] arr,int L,int R){
if (L==R){
return arr;
}
int M = ((R-L)>>1)+L;//保证int相加不会超过最大范围值,注意位移运算符优先级低于+、-,至少写成(R-L>>1)+L
//递归使左数组有序
process(arr,L,M);
//递归使右数组有序
process(arr,M+1,R);
//最后 调用排序算法,对已经有序的数组排序
return merge(arr,L,M,R);
}
/**归并思路:
* 用辅助空间保存将要排序的数组,用两个指针代表从中间一分为二的数组首位
* 循环比较左右指针处数组的值,将较小值添加到辅助空间,较小值所在子数组的指针和辅助空间指针向后移动一位,直到左右两个子数组有一个越界。
* 再将另一子数组剩下的值依次添加到辅助空间
* 最后用辅助空间替换掉数组对应排序范围的值
*/
public static int[] merge(int[] arr,int L,int M,int R){
int[] help = new int[R-L+1];//注意这里为什么是R-L+1.因为这里的help额外空间是给当前要排序是空间留的
int i=0;
int p1=L;
int p2=M+1;
while (p1<=M&&p2<=R){
help[i++]=arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while (p2<=R){
help[i++]=arr[p2++];
}
while (p1<=M){
help[i++]=arr[p1++];
}
//将当前排序空间的辅助数组的对应的值还给原数组
for (int j = 0; j < help.length; j++) {
arr[L+j]=help[j];//j++有++操作,复用j减少L++操作
}
return arr;
}
}