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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
| /**
* 归并排序 - 分治思想,将数组分割后合并
* 时间复杂度: O(n log n) 空间复杂度: O(n) 稳定
*/
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
// 递归分割左右两半
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 合并两个有序数组
merge(arr, left, mid, right);
printMergeStep(arr, left, mid, right);
}
}
/**
* 合并两个有序数组
*/
private static void merge(int[] arr, int left, int mid, int right) {
// 创建临时数组
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, k = 0;
// 比较两个数组的元素,将较小的放入临时数组
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
// 复制剩余元素
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
// 将临时数组复制回原数组
for (i = left; i <= right; i++) {
arr[i] = temp[i - left];
}
}
/**
* 归并排序可视化演示
*/
public static void mergeSortDemo() {
int[] arr = {38, 27, 43, 3, 9, 82, 10};
System.out.println("归并排序演示:");
System.out.println("初始数组: " + arrayToString(arr));
/*
归并排序过程(分治合并):
分割阶段:
[38, 27, 43, 3, 9, 82, 10]
↓ 分割
[38, 27, 43] [3, 9, 82, 10]
↓ ↓
[38][27, 43] [3, 9][82, 10]
↓ ↓
[38][27][43] [3][9][82][10]
合并阶段:
[27, 38, 43] [3, 9, 10, 82]
↓ 合并
[3, 9, 10, 27, 38, 43, 82]
*/
mergeSort(arr, 0, arr.length - 1);
System.out.println("排序完成: " + arrayToString(arr));
}
/**
* 自底向上的归并排序(迭代版本)
*/
public static void mergeSortBottomUp(int[] arr) {
int n = arr.length;
// 子数组大小从1开始,每次翻倍
for (int size = 1; size < n; size *= 2) {
// 合并相邻的子数组
for (int left = 0; left < n - size; left += 2 * size) {
int mid = left + size - 1;
int right = Math.min(left + 2 * size - 1, n - 1);
merge(arr, left, mid, right);
}
System.out.printf("子数组大小%d合并完成: %s%n", size, arrayToString(arr));
}
}
private static void printMergeStep(int[] arr, int left, int mid, int right) {
System.out.printf("合并[%d,%d]和[%d,%d]: %s%n",
left, mid, mid + 1, right, arrayToString(arr));
}
private static String arrayToString(int[] arr) {
return java.util.Arrays.toString(arr);
}
}
|