Skip to content

Commit 917f24d

Browse files
committed
重写java版归并排序
1 parent 6720ed9 commit 917f24d

File tree

3 files changed

+71
-65
lines changed

3 files changed

+71
-65
lines changed

5.mergeSort.md

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -143,47 +143,52 @@ func merge(left []int, right []int) []int {
143143
public class MergeSort implements IArraySort {
144144

145145
@Override
146-
public int[] sort(int[] sourceArray) throws Exception {
147-
// 对 arr 进行拷贝,不改变参数内容
148-
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
146+
public int[] sort(int[] arr) throws Exception {
147+
mergeSort(arr, 0, arr.length - 1);
148+
return arr;
149+
}
149150

150-
if (arr.length < 2) {
151-
return arr;
151+
private void mergeSort(int[] arr, int left, int right) {
152+
if (left >= right) {
153+
return;
152154
}
153-
int middle = (int) Math.floor(arr.length / 2);
154155

155-
int[] left = Arrays.copyOfRange(arr, 0, middle);
156-
int[] right = Arrays.copyOfRange(arr, middle, arr.length);
156+
int mid = (right + left) / 2;
157157

158-
return merge(sort(left), sort(right));
158+
//
159+
mergeSort(arr, left, mid);
160+
mergeSort(arr, mid + 1, right);
161+
//
162+
merge(arr, left, mid, right);
159163
}
160164

161-
protected int[] merge(int[] left, int[] right) {
162-
int[] result = new int[left.length + right.length];
163-
int i = 0;
164-
while (left.length > 0 && right.length > 0) {
165-
if (left[0] <= right[0]) {
166-
result[i++] = left[0];
167-
left = Arrays.copyOfRange(left, 1, left.length);
165+
166+
/**
167+
* 主要思想, 两个已经排序好的数组, 如何归并
168+
* 当元素个数趋近单个元素时, 归并即为排序过程
169+
*/
170+
private void merge(int[] arr, int left, int mid, int right) {
171+
int[] tmp = new int[right - left + 1];
172+
173+
int i = left;
174+
int j = mid + 1;
175+
int k = 0;
176+
177+
while (i <= mid && j <= right) {
178+
if (arr[i] <= arr[j]) { //取等号, 优先匹配左边数组予以填充
179+
tmp[k++] = arr[i++];
168180
} else {
169-
result[i++] = right[0];
170-
right = Arrays.copyOfRange(right, 1, right.length);
181+
tmp[k++] = arr[j++];
171182
}
172183
}
173184

174-
while (left.length > 0) {
175-
result[i++] = left[0];
176-
left = Arrays.copyOfRange(left, 1, left.length);
177-
}
178-
179-
while (right.length > 0) {
180-
result[i++] = right[0];
181-
right = Arrays.copyOfRange(right, 1, right.length);
182-
}
185+
//队尾的直接填充
186+
while (i <= mid) tmp[k++] = arr[i++];
187+
while (j <= right) tmp[k++] = arr[j++];
183188

184-
return result;
189+
//覆盖原数组
190+
System.arraycopy(tmp, 0, arr, left, tmp.length);
185191
}
186-
187192
}
188193
```
189194

src/java/main/MergeSort.java

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,55 @@
1-
import java.util.Arrays;
2-
31
/**
42
* 归并排序
3+
* @author qrqhuangcy
4+
* @date 2020/5/4
55
*/
66
public class MergeSort implements IArraySort {
77

88
@Override
99
public int[] sort(int[] arr) throws Exception {
10-
if (arr.length < 2) {
11-
return arr;
10+
mergeSort(arr, 0, arr.length - 1);
11+
return arr;
12+
}
13+
14+
private void mergeSort(int[] arr, int left, int right) {
15+
if (left >= right) {
16+
return;
1217
}
13-
int middle = (int) Math.floor(arr.length / 2);
1418

15-
int[] left = Arrays.copyOfRange(arr, 0, middle);
16-
int[] right = Arrays.copyOfRange(arr, middle, arr.length);
19+
int mid = (right + left) / 2;
1720

18-
return merge(sort(left), sort(right));
21+
//分
22+
mergeSort(arr, left, mid);
23+
mergeSort(arr, mid + 1, right);
24+
//治
25+
merge(arr, left, mid, right);
1926
}
2027

21-
protected int[] merge(int[] left, int[] right) {
22-
int[] result = new int[left.length + right.length];
23-
int l = 0, r = 0, len = 0;
24-
while (len < left.length + right.length) {
25-
if (left[l] <= right[r]) {
26-
result[len++] = left[l++];
27-
28-
if (l == left.length) {
29-
for (int i = r; i < right.length; i++) {
30-
result[len++] = right[r++];
31-
}
32-
}
33-
} else {
34-
result[len++] = right[r++];
3528

36-
if (r == right.length) {
37-
for (int i = l; i < left.length; i++) {
38-
result[len++] = left[l++];
39-
}
40-
}
29+
/**
30+
* 主要思想, 两个已经排序好的数组, 如何归并
31+
* 当元素个数趋近单个元素时, 归并即为排序过程
32+
*/
33+
private void merge(int[] arr, int left, int mid, int right) {
34+
int[] tmp = new int[right - left + 1];
35+
36+
int i = left;
37+
int j = mid + 1;
38+
int k = 0;
39+
40+
while (i <= mid && j <= right) {
41+
if (arr[i] <= arr[j]) { //取等号, 优先匹配左边数组予以填充
42+
tmp[k++] = arr[i++];
43+
} else {
44+
tmp[k++] = arr[j++];
4145
}
4246
}
4347

44-
return result;
45-
}
48+
//队尾的直接填充
49+
while (i <= mid) tmp[k++] = arr[i++];
50+
while (j <= right) tmp[k++] = arr[j++];
4651

52+
//覆盖原数组
53+
System.arraycopy(tmp, 0, arr, left, tmp.length);
54+
}
4755
}

src/java/test/ArraySortTest.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,6 @@ public void mergeSort() throws Exception {
101101
assertArrayEquals(sortedArray, new MergeSort().sort(array));
102102
}
103103

104-
@Test
105-
public void mergeSort_merge() throws Exception {
106-
assertArrayEquals(new int[]{1, 2}, new MergeSort().merge(new int[]{1, 2}, new int[]{}));
107-
assertArrayEquals(new int[]{1, 2}, new MergeSort().merge(new int[]{1}, new int[]{2}));
108-
assertArrayEquals(new int[]{1, 2, 3}, new MergeSort().merge(new int[]{1, 3}, new int[]{2}));
109-
}
110-
111104
@Test
112105
public void quickSort() throws Exception {
113106
assertArrayEquals(sortedArray, new QuickSort().sort(array));

0 commit comments

Comments
 (0)