11package algorithm ;
22
3+ import java .util .Arrays ;
4+
35public 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}
0 commit comments