1
1
package algorithm ;
2
2
3
+ import java .util .Arrays ;
4
+
3
5
public class Sort {
4
6
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
+
5
16
private Sort () {
6
17
}
7
18
@@ -30,17 +41,28 @@ public static <T extends Comparable> void selectSort(T[] arr) {
30
41
*
31
42
* 对近乎有序的数组的排序效率非常高
32
43
*
44
+ * 原始方法 多次交换,浪费时间
33
45
*/
34
46
public static <T extends Comparable > void insertSort (T [] arr ) {
35
47
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 ++) {
44
66
int j = i ;// i元素最终要插入的位置
45
67
T temp = arr [i ];
46
68
for (; j > 0 && arr [j - 1 ].compareTo (temp ) > 0 ; j --) {
@@ -52,11 +74,12 @@ public static <T extends Comparable> void insertSort(T[] arr) {
52
74
53
75
/*
54
76
* 基本冒泡排序
77
+ *
55
78
*/
56
79
public static <T extends Comparable > void bubbleSort (T [] arr ) {
57
80
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 ++) {
60
83
if (arr [j + 1 ].compareTo (arr [j ]) < 0 ) {
61
84
T temp = arr [j + 1 ];
62
85
arr [j + 1 ] = arr [j ];
@@ -66,8 +89,120 @@ public static <T extends Comparable> void bubbleSort(T[] arr) {
66
89
}
67
90
}
68
91
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 ) {
70
98
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
+ }
71
109
}
72
110
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
+ }
73
208
}
0 commit comments