Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d4a020a

Browse files
committed
merge sort
1 parent f4319cf commit d4a020a

File tree

2 files changed

+144
-174
lines changed

2 files changed

+144
-174
lines changed

‎src/main/java/grey/algorithm/Code_0014_MergeSort.java

Lines changed: 129 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -16,179 +16,134 @@
1616

1717
public class Code_0014_MergeSort {
1818

19-
// merge sort的递归写法
20-
public static void sort(int[] arr) {
21-
mergeSort(arr, 0, arr.length - 1);
22-
}
23-
24-
// 递归解法
25-
public static void mergeSort(int[] arr, int l, int r) {
26-
if (l >= r) {
27-
// 终止条件
28-
return;
29-
}
30-
int mid = l + ((r - l) >> 1);
31-
mergeSort(arr, l, mid);
32-
mergeSort(arr, mid + 1, r);
33-
merge2(arr, l, mid, r);
34-
}
35-
36-
public static void merge2(int[] arr, int l, int m, int r) {
37-
int[] help = new int[r - l + 1];
38-
int s = l;
39-
int e = m + 1;
40-
int i = 0;
41-
while (s <= m && e <= r) {
42-
if (arr[s] <= arr[e]) {
43-
help[i++] = arr[s++];
44-
} else {
45-
help[i++] = arr[e++];
46-
}
47-
}
48-
while (s <= m) {
49-
help[i++] = arr[s++];
50-
}
51-
while (e <= r) {
52-
help[i++] = arr[e++];
53-
}
54-
for (i = 0; i < help.length; i++) {
55-
arr[l++] = help[i];
56-
}
57-
}
58-
59-
// 迭代版本的merge sort
60-
public static void mergeSort2(int[] arr, int l, int r) {
61-
if (arr == null || arr.length < 2) {
62-
return;
63-
}
64-
65-
int n = arr.length;
66-
67-
// 1. 外层循环:控制每次要合并的子数组的大小(subArraySize)
68-
// subArraySize 从 1 开始,每次翻倍,表示当前有序子数组的长度
69-
// 依次为 1, 2, 4, 8, ...
70-
for (int subArraySize = 1; subArraySize < n; subArraySize = subArraySize * 2) {
71-
72-
// 2. 内层循环:从左到右,找到每一对需要合并的子数组,然后调用merge
73-
// leftStart 是每一对子数组中,左边那个数组的起始位置
74-
for (int leftStart = 0; leftStart < n; leftStart = leftStart + subArraySize * 2) {
75-
76-
// 确定左子数组的边界
77-
// 左数组是 arr[leftStart ... mid]
78-
int mid = leftStart + subArraySize - 1;
79-
80-
// 如果 mid 已经越界,说明在 leftStart 之后连一个完整的左数组都凑不齐了
81-
// 那么剩下的部分自然就是有序的,无需再合并,直接跳出内层循环
82-
if (mid >= n - 1) {
83-
break;
84-
}
85-
86-
// 确定右子数组的边界
87-
// 右数组是 arr[mid + 1 ... rightEnd]
88-
// 这里用 Math.min 是为了防止右边界越界
89-
// 比如数组长度为13,当合并size=4的子数组时,最后一组是 arr[8...11] 和 arr[12...12]
90-
// 此时 rightEnd 就不能是 8 + 4*2 - 1 = 15,而应该是 n - 1 = 12
91-
int rightEnd = Math.min(leftStart + subArraySize * 2 - 1, n - 1);
92-
93-
// 找到了左右两个要合并的有序子数组,执行合并
94-
// System.out.printf("合并: subArraySize=%d, merge(arr, %d, %d, %d)%n", subArraySize, leftStart, mid, rightEnd);
95-
merge(arr, leftStart, mid, rightEnd);
96-
}
97-
// System.out.println("--- subArraySize=" + subArraySize + " 的一轮合并结束 ---");
98-
}
99-
}
100-
101-
private static void merge(int[] arr, int l, int m, int r) {
102-
int i = 0;
103-
int s = l;
104-
int e = m + 1;
105-
int[] help = new int[r - l + 1];
106-
while (s <= m && e <= r) {
107-
if (arr[s] <= arr[e]) {
108-
help[i++] = arr[s++];
109-
} else {
110-
help[i++] = arr[e++];
111-
}
112-
}
113-
while (s <= m) {
114-
help[i++] = arr[s++];
115-
}
116-
117-
while (e <= r) {
118-
help[i++] = arr[e++];
119-
}
120-
for (i = 0; i < help.length; i++) {
121-
arr[l++] = help[i];
122-
}
123-
}
124-
125-
public static void swap(int[] arr, int i, int j) {
126-
if (null == arr || arr.length <= 1) {
127-
return;
128-
}
129-
int tmp = arr[i];
130-
arr[i] = arr[j];
131-
arr[j] = tmp;
132-
}
133-
134-
public static void main(String[] args) {
135-
136-
// 数组长度1~500,等概率随机
137-
int num = 500;
138-
// 每个值的大小在1~1024,等概率随机
139-
int value = 1024;
140-
// 测试次数
141-
int testTimes = 50000;
142-
System.out.println("测试开始");
143-
for (int i = 0; i < testTimes; i++) {
144-
int[] arr = generateArray(num, value);
145-
int[] copyArray1 = copyArray(arr);
146-
int[] copyArray2 = copyArray(arr);
147-
Arrays.sort(arr);
148-
sort(copyArray1);
149-
mergeSort2(copyArray2, 0, copyArray2.length - 1);
150-
if (!sameValue(arr, copyArray1)) {
151-
System.out.println("出错了!");
152-
break;
153-
}
154-
if (!sameValue(arr, copyArray2)) {
155-
System.out.println("出错了!");
156-
break;
157-
}
158-
}
159-
System.out.println("测试结束");
160-
}
161-
162-
private static boolean sameValue(int[] arr1, int[] arr2) {
163-
if (null == arr1) {
164-
return null != arr2;
165-
}
166-
if (null == arr2) {
167-
return null != arr1;
168-
}
169-
if (arr1.length != arr2.length) {
170-
return false;
171-
}
172-
for (int i = 0; i < arr1.length; i++) {
173-
if (arr1[i] != arr2[i]) {
174-
return false;
175-
}
176-
}
177-
return true;
178-
}
179-
180-
private static int[] generateArray(int num, int value) {
181-
int[] arr = new int[(int) (Math.random() * num) + 1];
182-
for (int i = 0; i < arr.length; i++) {
183-
arr[i] = (int) (Math.random() * value) + 1;
184-
}
185-
return arr;
186-
}
187-
188-
private static int[] copyArray(int[] arr) {
189-
int[] copyArray = new int[arr.length];
190-
System.arraycopy(arr, 0, copyArray, 0, copyArray.length);
191-
return copyArray;
192-
}
19+
// merge sort的递归写法
20+
public static void sort(int[] arr) {
21+
mergeSort(arr, 0, arr.length - 1);
22+
}
23+
24+
// 递归解法
25+
public static void mergeSort(int[] arr, int l, int r) {
26+
if (l >= r) {
27+
// 终止条件
28+
return;
29+
}
30+
int mid = l + ((r - l) >> 1);
31+
mergeSort(arr, l, mid);
32+
mergeSort(arr, mid + 1, r);
33+
merge(arr, l, mid, r);
34+
}
35+
36+
public static void merge(int[] arr, int l, int m, int r) {
37+
int[] help = new int[r - l + 1];
38+
int s = l;
39+
int e = m + 1;
40+
int i = 0;
41+
while (s <= m && e <= r) {
42+
if (arr[s] <= arr[e]) {
43+
help[i++] = arr[s++];
44+
} else {
45+
help[i++] = arr[e++];
46+
}
47+
}
48+
while (s <= m) {
49+
help[i++] = arr[s++];
50+
}
51+
while (e <= r) {
52+
help[i++] = arr[e++];
53+
}
54+
for (i = 0; i < help.length; i++) {
55+
arr[l++] = help[i];
56+
}
57+
}
58+
59+
// 迭代版本的merge sort
60+
public static void sort2(int[] arr) {
61+
if (arr == null || arr.length < 2) {
62+
return;
63+
}
64+
int n = arr.length;
65+
for (int subSize = 1; subSize < n; subSize <<= 1) {
66+
// 每组1,2,4,8这样扩
67+
for (int leftIndex = 0; leftIndex < n; leftIndex = leftIndex + (subSize * 2)) {
68+
// 第一组的起始位置
69+
int m = leftIndex + subSize - 1;
70+
if (m >= n - 1) {
71+
// 没有右组,已经排好了
72+
break;
73+
}
74+
int rightEnd = Math.min(leftIndex + (subSize * 2) - 1, n - 1);
75+
merge(arr, leftIndex, m, rightEnd);
76+
}
77+
}
78+
}
79+
80+
public static void swap(int[] arr, int i, int j) {
81+
if (null == arr || arr.length <= 1) {
82+
return;
83+
}
84+
int tmp = arr[i];
85+
arr[i] = arr[j];
86+
arr[j] = tmp;
87+
}
88+
89+
public static void main(String[] args) {
90+
91+
// 数组长度1~500,等概率随机
92+
int num = 500;
93+
// 每个值的大小在1~1024,等概率随机
94+
int value = 1024;
95+
// 测试次数
96+
int testTimes = 50000;
97+
System.out.println("测试开始");
98+
for (int i = 0; i < testTimes; i++) {
99+
int[] arr = generateArray(num, value);
100+
int[] copyArray1 = copyArray(arr);
101+
int[] copyArray2 = copyArray(arr);
102+
Arrays.sort(arr);
103+
sort(copyArray1);
104+
sort2(copyArray2);
105+
if (!sameValue(arr, copyArray1)) {
106+
System.out.println("出错了!");
107+
break;
108+
}
109+
if (!sameValue(arr, copyArray2)) {
110+
System.out.println("出错了!");
111+
break;
112+
}
113+
}
114+
System.out.println("测试结束");
115+
}
116+
117+
private static boolean sameValue(int[] arr1, int[] arr2) {
118+
if (null == arr1) {
119+
return null != arr2;
120+
}
121+
if (null == arr2) {
122+
return null != arr1;
123+
}
124+
if (arr1.length != arr2.length) {
125+
return false;
126+
}
127+
for (int i = 0; i < arr1.length; i++) {
128+
if (arr1[i] != arr2[i]) {
129+
return false;
130+
}
131+
}
132+
return true;
133+
}
134+
135+
private static int[] generateArray(int num, int value) {
136+
int[] arr = new int[(int) (Math.random() * num) + 1];
137+
for (int i = 0; i < arr.length; i++) {
138+
arr[i] = (int) (Math.random() * value) + 1;
139+
}
140+
return arr;
141+
}
142+
143+
private static int[] copyArray(int[] arr) {
144+
int[] copyArray = new int[arr.length];
145+
System.arraycopy(arr, 0, copyArray, 0, copyArray.length);
146+
return copyArray;
147+
}
193148

194149
}

‎src/main/java/grey/algorithm/Main.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
3+
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
4+
*/
5+
package grey.algorithm;
6+
7+
/**
8+
*
9+
* @author Grey
10+
*/
11+
public class Main {
12+
public static void main(String[] arr) {
13+
// 用作测试
14+
}
15+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /