標籤:
繼續排序演算法
4.冒泡排序
從第一個開始,跟後面一個數比較,如果比後面大就交換位置,這樣沒完成一輪,就可以把最大的選出來
public static <T extends Comparable<T>> T[] genericBubbleSort(T[] a) { int n = a.length; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (a[j].compareTo(a[j + 1]) > 0) { T temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } return a; }
改進上面的冒泡排序
方案一:設定一標誌性變數pos,用於記錄每趟排序中最後一次進行交換的位置。由於pos位置之後的記錄均已交換到位,
故在進行下一趟排序時只要掃描到pos位置即可
public static <T extends Comparable<T>> T[] genericBubbleSortGai(T[] a) { int n = a.length; int i = n - 1; while (i > 0) { int pos = 0; for (int j = 0; j < i; j++) { if (a[j].compareTo(a[j + 1]) > 0) { pos = j; T temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } i = pos; } return a; }
改進方案二:
兩邊同時進行 先找最大的 然後找最小的
public static <T extends Comparable<T>> T[] genericBubbleSortGai2(T[] a) { int n = a.length; int low = 0, high = n - 1; int j; T tmp; while (low < high) { for (j = low; j < high; j++) { if (a[j].compareTo(a[j + 1]) > 0) { tmp = a[j]; a[j] = a[j + 1]; a[j + 1] = tmp; } } high--; for (j = high; j > low; j--) { if (a[j].compareTo(a[j - 1]) < 0) { tmp = a[j]; a[j] = a[j - 1]; a[j - 1] = tmp; } } low++; } return a; }
改進方案三:
設定一個標誌 如果有一趟沒有發生交換 則排序完成
public static <T extends Comparable<T>> T[] genericbubblesortgai3(T[] a) { int n = a.length; boolean flag = true; for (int i = 0; i < n - 1; i++) { if (!flag) { return a; } flag = false; for (int j = 0; j < n - i - 1; j++) { if (a[j].compareTo(a[j + 1]) > 0) { flag = true; T temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } return a; }
5.快速排序
<快速排序> 基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,
* 然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。快速排序是一種不穩定的排序演算法
public static <T extends Comparable<T>> T[] QuickSortStart(T[] list) { quickSort(list, 0, list.length - 1); return list; } private static <T extends Comparable<T>> void quickSort(T[] list, int first, int last) { if (last > first) { int povitIndex = partition(list, first, last); quickSort(list, first, povitIndex - 1); quickSort(list, povitIndex + 1, last); } } private static <T extends Comparable<T>> int partition(T[] list, int first, int last) { /* * 把數組分為兩組,將比povit小的數放在它前面,比povit大的數放在它後面 */ T povit = list[first]; int low = first + 1; int high = last; while (high > low) { while (high > low && list[low].compareTo(povit) <= 0) low++; while (low <= high && list[high].compareTo(povit) > 0) high--; if (high > low) { T temp = list[high]; list[high] = list[low]; list[low] = temp; } } while (high > first && list[high].compareTo(povit) >= 0) high--; if (povit.compareTo(list[high]) > 0) { list[first] = list[high]; list[high] = povit; return high; } return first; }
6.歸併排序
將一個序列一直對半拆分,知道不能拆分,然後開始歸併,歸併採用插入排序
public static <T extends Comparable<T>> T[] mergesort(T[] a) { T[] temp = a.clone(); a = msort(a, temp, 0, a.length); return a; } public static <T extends Comparable<T>> T[] msort(T[] a, T[] temp, int first, int last) { if (first + 1 < last) { int mid = (first + last) / 2; msort(a, temp, first, mid); msort(a, temp, mid, last); int index1 = first; int index2 = mid; int index3 = first; while (index1 < mid && index2 < last) { if (a[index1].compareTo(a[index2]) < 0) { temp[index3] = a[index1]; index1++; } else { temp[index3] = a[index2]; index2++; } index3++; } while (index1 < mid) { temp[index3++] = a[index1++]; } while (index2 < last) { temp[index3++] = a[index2++]; } for (int i = first; i < last; i++) a[i] = temp[i]; } return a; }
感覺就是把代碼複製上去了,說的不是很清楚,,,還有一個堆排序沒有寫
最後對上面的排序演算法做了下測試,產生10000個int數,進行排序,算時間
1.歸併排序 50~60 ms之間
2.簡單選擇排序 135~155 ms之間
3.選擇排序 220 ms //可能是我資料沒選好,10000個數,產生的隨機數也是0~10000
4.快速排序 30ms 左右
5.冒泡排序 改進方案二快點 280ms
6.插入排序 70ms左右
然後還是10000個隨機數,範圍換成0~100000,結果基本每種排序的時間更短
所以排序的時間長短是和資料本身有關係的
排序演算法 java實現2