1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
public class Main {
public static int[] sortArray(int[] nums){
// 数组长度大于1时才需要排序(长度为0或1默认有序)
if(nums.length>1){
mergeSort(nums);
}
return nums;
}
// 定义最大数组长度
public static int MAXN = 50001;
// 辅助数组:用于归并过程中临时存储元素,避免每次合并都新建数组
public static int[] help = new int[MAXN];
public static void mergeSort(int[] arr){
// 从数组的0号位置到最后一个位置(arr.length-1)进行排序
sort(arr,0,arr.length-1);
}
public static void sort(int[] arr,int l,int r){
// 当区间只有一个元素时(l==r),无需排序,直接返回
if(l==r){
return;
}
// 计算中间位置(等价于(l+r)/2,但用位运算>>1避免溢出,且效率更高)
int m = l + ((r - l) >> 1);
// 递归排序左半区间 [l, m]
sort(arr,l,m);
// 递归排序右半区间 [m+1, r]
sort(arr,m+1,r);
// 合并左右两个已排序的区间
merge(arr,l,m,r);
}
public static void merge(int[] arr,int l,int m,int r){
int i = l; // 辅助数组help的当前填充位置(从l开始)
int a = l; // 左区间的遍历指针(从l开始)
int b = m + 1; // 右区间的遍历指针(从m+1开始)
// 1. 双指针遍历左右区间,将较小的元素依次放入help
while(a <= m && b <= r){
// 谁小就先放谁,相等时优先放左区间元素(保证稳定性)
help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];
}
// 2. 左区间还有剩余元素,全部放入help(右区间已遍历完)
while(a <= m){
help[i++] = arr[a++];
}
// 3. 右区间还有剩余元素,全部放入help(左区间已遍历完)
while(b <= r){
help[i++] = arr[b++];
}
// 4. 将help中排序好的元素拷贝回原数组的[l, r]区间
for(i = l; i <= r; i++){
arr[i] = help[i];
}
}
}
|