Skip to content

Commit 5eb4963

Browse files
author
xulw
committed
mergeSort & bubbleSort added
1 parent fe91244 commit 5eb4963

File tree

7 files changed

+215
-42
lines changed

7 files changed

+215
-42
lines changed

bin/algorithm/AlgoTest$1.class

785 Bytes
Binary file not shown.

bin/algorithm/AlgoTest.class

103 Bytes
Binary file not shown.

bin/algorithm/Sort.class

2.29 KB
Binary file not shown.

bin/algorithm/SortTestHelper.class

1.51 KB
Binary file not shown.

src/algorithm/AlgoTest.java

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,39 @@
11
package algorithm;
22

3+
import java.util.Arrays;
4+
35
public class AlgoTest {
46

5-
public static final int N = 2000;
7+
public static final int N = 50000;
68
public static final int RANGE_R = 20;
79
public static final int RANGE_L = 400;
810
public static final int MAX_OF_STUDENT_NUM = 2000;
911

10-
public static final String AFTER_TEXT = "\n after : ";
12+
public static final String CLASS_NAME = "algorithm.Sort";
1113

12-
public static void testSelectionSort() {
13-
Integer[] arr = new Integer[N];
14-
arr = SortTestHelper.generateRandomArray(N, RANGE_R, RANGE_L);
15-
SortTestHelper.printArray(arr);
16-
System.out.println(AFTER_TEXT);
17-
Sort.selectSort(arr);
18-
SortTestHelper.printArray(arr);
14+
public AlgoTest() {
15+
// Integer[] arr = SortTestHelper.generateNearlyOrderedArray(N, 100);
16+
Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 400);
17+
handleSort(Sort.INSERT_SORT, arr.clone());
18+
handleSort(Sort.INSERT_SORT_AD, arr.clone());
19+
handleSort(Sort.BUBBLE_SORT, arr.clone());
20+
// handleSort(Sort.BUBBLE_SORT_AD_V1, arr.clone());
21+
// handleSort(Sort.BUBBLE_SORT_AD_V3, arr.clone());
22+
handleSort(Sort.MERGE_SORT, arr.clone());
23+
handleSort(Sort.SELECT_SORT, arr.clone());
1924
}
2025

21-
public static void testBubbleSort() {
22-
Integer[] arr = new Integer[N];
23-
arr = SortTestHelper.generateRandomArray(N, RANGE_R, RANGE_L);
24-
SortTestHelper.printArray(arr);
25-
Sort.bubbleSort(arr);
26-
SortTestHelper.printArray(arr);
26+
private static <T extends Comparable> void handleSort(String sortName, T[] arr) {
27+
new Thread(new Runnable() {
28+
@Override
29+
public void run() {
30+
SortTestHelper.testSort(sortName, CLASS_NAME, arr);
31+
}
32+
}).start();
2733
}
28-
34+
2935
public static void main(String[] args) {
30-
// testSelectionSort();
31-
// Student[] ss = Student.generateStudentArray(N, MAX_OF_STUDENT_NUM);
32-
// Integer[] arr = SortTestHelper.generateRandomArray(N, RANGE_R, RANGE_L);
33-
// Sort.insertSort(arr);
34-
// SortTestHelper.printArray(arr);
35-
// System.out.println(SortTestHelper.isSorted(arr));
36-
//
37-
//
38-
testBubbleSort();
36+
new AlgoTest();
3937
}
40-
41-
42-
}
43-
4438

39+
}

src/algorithm/Sort.java

Lines changed: 146 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
package algorithm;
22

3+
import java.util.Arrays;
4+
35
public class Sort {
46

7+
public static final String SELECT_SORT = "selectSort";
8+
public static final String INSERT_SORT = "insertSort";
9+
public static final String INSERT_SORT_AD = "insertSortImproved";
10+
public static final String BUBBLE_SORT = "bubbleSort";
11+
public static final String BUBBLE_SORT_AD_V1 = "bubbleSortImprovedV1";
12+
public static final String BUBBLE_SORT_AD_V2 = "bubbleSortImprovedV2";
13+
public static final String BUBBLE_SORT_AD_V3 = "bubbleSortImprovedV3";
14+
public static final String MERGE_SORT = "mergeSort";
15+
516
private Sort() {
617
}
718

@@ -30,17 +41,28 @@ public static <T extends Comparable> void selectSort(T[] arr) {
3041
*
3142
* 对近乎有序的数组的排序效率非常高
3243
*
44+
* 原始方法 多次交换,浪费时间
3345
*/
3446
public static <T extends Comparable> void insertSort(T[] arr) {
3547
for (int i = 1; i < arr.length; i++) {
36-
// 原始方法 多次交换,浪费时间
37-
// for (int j = i; j > 0 && arr[j].compareTo(arr[j - 1]) < 0; j--) {
38-
// // 右边比左边小,则交换
39-
// T temp = arr[j];
40-
// arr[j] = arr[j - 1];
41-
// arr[j - 1] = temp;
42-
// }
43-
// 优化后的方法 大量减少交换
48+
49+
for (int j = i; j > 0 && arr[j].compareTo(arr[j - 1]) < 0; j--) {
50+
// 右边比左边小,则交换
51+
T temp = arr[j];
52+
arr[j] = arr[j - 1];
53+
arr[j - 1] = temp;
54+
}
55+
56+
}
57+
}
58+
59+
/*
60+
* 改进插入排序
61+
*
62+
* 优化后的方法 大量减少交换
63+
*/
64+
public static <T extends Comparable> void insertSortImproved(T[] arr) {
65+
for (int i = 0; i < arr.length; i++) {
4466
int j = i;// i元素最终要插入的位置
4567
T temp = arr[i];
4668
for (; j > 0 && arr[j - 1].compareTo(temp) > 0; j--) {
@@ -52,11 +74,12 @@ public static <T extends Comparable> void insertSort(T[] arr) {
5274

5375
/*
5476
* 基本冒泡排序
77+
*
5578
*/
5679
public static <T extends Comparable> void bubbleSort(T[] arr) {
5780

58-
for (int i = 1; i < arr.length; i++) {
59-
for (int j = 0; j < arr.length - i; j++) {
81+
for (int i = 0; i < arr.length - 1; i++) {
82+
for (int j = 0; j < arr.length - 1 - i; j++) {
6083
if (arr[j + 1].compareTo(arr[j]) < 0) {
6184
T temp = arr[j + 1];
6285
arr[j + 1] = arr[j];
@@ -66,8 +89,120 @@ public static <T extends Comparable> void bubbleSort(T[] arr) {
6689
}
6790
}
6891

69-
public static <T extends Comparable> void bubbleSortImproved(T[] arr) {
92+
/*
93+
* 改进的冒泡算法
94+
*
95+
* 记录最大的位置
96+
*/
97+
public static <T extends Comparable> void bubbleSortImprovedV1(T[] arr) {
7098

99+
for (int i = 0; i < arr.length - 1; i++) {
100+
int indexOfMax = arr.length - 1 - i;
101+
for (int j = 0; j < arr.length - 1 - i; j++) {
102+
if (arr[j].compareTo(arr[indexOfMax]) > 0)
103+
indexOfMax = j;
104+
}
105+
T temp = arr[indexOfMax];
106+
arr[indexOfMax] = arr[arr.length - 1 - i];
107+
arr[arr.length - 1 - i] = temp;
108+
}
71109
}
72110

111+
/*
112+
* 用一个标志,如果某一趟没发生交换,说明已经有序
113+
*
114+
* 并且最后面的元素是有序的,不需要参与后面的循环
115+
*/
116+
public static <T extends Comparable> void bubbleSortImprovedV2(T[] arr) {
117+
118+
int n = arr.length;
119+
boolean swapped = false;
120+
121+
do {
122+
swapped = false;
123+
for (int i = 1; i < n; i++)
124+
if (arr[i - 1].compareTo(arr[i]) > 0) {
125+
T temp = arr[i - 1];
126+
arr[i - 1] = arr[i];
127+
arr[i] = temp;
128+
swapped = true;
129+
}
130+
131+
// 优化, 每一趟Bubble Sort都将最大的元素放在了最后的位置
132+
// 所以下一次排序, 最后的元素可以不再考虑
133+
n--;
134+
} while (swapped);
135+
}
136+
137+
/*
138+
* 第三次改进
139+
*/
140+
public static <T extends Comparable> void bubbleSortImprovedV3(T[] arr) {
141+
142+
int n = arr.length;
143+
int newn; // 使用newn进行优化
144+
145+
do {
146+
newn = 0;
147+
for (int i = 1; i < n; i++)
148+
if (arr[i - 1].compareTo(arr[i]) > 0) {
149+
T temp = arr[i - 1];
150+
arr[i - 1] = arr[i];
151+
arr[i] = temp;
152+
// 记录最后一次的交换位置,在此之后的元素在下一轮扫描中均不考虑
153+
newn = i;
154+
}
155+
n = newn;
156+
} while (newn > 0);
157+
}
158+
159+
public static <T extends Comparable> void mergeSort(T[] arr) {
160+
subMergeSort(arr, 0, arr.length - 1);
161+
}
162+
163+
// 递归使用归并排序,对arr[l...r]的范围进行排序
164+
private static <T extends Comparable> void subMergeSort(T[] arr, int l, int r) {
165+
// 已经排完
166+
if (l >= r)
167+
return;
168+
169+
// 防止两个整形相加越界
170+
long sum = r + l;
171+
int middle = (int) (sum / 2);
172+
173+
subMergeSort(arr, l, middle);
174+
subMergeSort(arr, middle + 1, r);
175+
merge(arr, l, middle, r);
176+
}
177+
178+
// 将arr[l...mid]和arr[mid+1...r]两部分进行归并
179+
private static <T extends Comparable> void merge(T[] arr, int l, int mid, int r) {
180+
181+
T[] aux = Arrays.copyOfRange(arr, l, r + 1);
182+
183+
int i = l;// 指向前半部分的起始位置`
184+
int j = mid + 1;// 指向后半部分的起始位置
185+
int k = l;// 指向原数组的插入位置
186+
187+
for (; k <= r; k++) {
188+
if (i > mid) {
189+
// 左边已经排完
190+
arr[k] = aux[j - l];
191+
j++;
192+
} else if (j > r) {
193+
// 右边已经排完了
194+
arr[k] = aux[i - l];
195+
i++;
196+
} else if (aux[i - l].compareTo(aux[j - l]) < 0) {
197+
arr[k] = aux[i - l];
198+
i++;
199+
} else {
200+
arr[k] = aux[j - l];
201+
j++;
202+
}
203+
}
204+
205+
206+
207+
}
73208
}

src/algorithm/SortTestHelper.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package algorithm;
22

3+
import java.lang.reflect.Method;
4+
import java.lang.reflect.Type;
35
import java.util.Random;
46

57
public class SortTestHelper {
@@ -16,6 +18,24 @@ public static Integer[] generateRandomArray(int n, int rangeR, int rangeL) {
1618
return arr;
1719
}
1820

21+
public static Integer[] generateNearlyOrderedArray(int n, int swapTimes) {
22+
Integer[] arr = new Integer[n];
23+
// 有序集合
24+
for (int i = 0; i < n; i++) {
25+
arr[i] = i;
26+
}
27+
// 进行交换
28+
for (int j = 0; j < swapTimes; j++) {
29+
int a = (int) (Math.random() * n);
30+
int b = (int) (Math.random() * n);
31+
int t = arr[a];
32+
arr[a] = arr[b];
33+
arr[b] = t;
34+
}
35+
36+
return arr;
37+
}
38+
1939
/*
2040
* 输出数组
2141
*/
@@ -39,6 +59,29 @@ public static <T extends Comparable> boolean isSorted(T[] arr) {
3959
return true;
4060
}
4161

42-
43-
62+
/*
63+
* 测试排序算法的效率
64+
*
65+
*/
66+
public static <T extends Comparable> void testSort(String sortName, String className, T[] arr) {
67+
try {
68+
69+
Class sortClass = Class.forName(className);
70+
Method sort = sortClass.getMethod(sortName, Comparable[].class);
71+
72+
long start = System.currentTimeMillis();
73+
// 需要强转,因为接收的参数是可变参数,如果传入的是数组,则展开之后会出现错误,
74+
// 所以需要进行强制转换为一个参数,反正接收的参数也是 Object
75+
sort.invoke(null, (Object) arr);
76+
long end = System.currentTimeMillis();
77+
if (isSorted(arr))
78+
System.out.println("\n" + sortName + " cost : " + (end - start));
79+
else
80+
System.out.println("\n" + sortName + " cost : 9999999999");
81+
82+
} catch (Exception e) {
83+
e.printStackTrace();
84+
}
85+
}
86+
4487
}

0 commit comments

Comments
 (0)