本文總結了常見高頻的關於排序的算法考察。算法
1.冒泡排序
冒泡排序的思想是元素兩兩比較,將較大或者較小的元素往一端進行移動shell
public static void bubble(int[] array) { for (int i = 0; i < array.length - 1; i++) { for (int j = 0; j + 1 < array.length - i; j++) { if (array[j] > array[j + 1]) { int tmp = array[j]; array[j] = array[j + 1]; array[j + 1] = tmp; } } } }
2.快速排序
快速排序的思想是隨機選取一個數字,並以這個數字爲臨界點,將數組分紅小於臨界點的的子數組和大於臨界點的子數組,並遞歸這個過程,便可實現最終的排序。後端
public static void quick(int[] array, int begin, int end) { if (begin >= end) { return; } int beginRange = begin; int endRange = end; int compareInt = array[begin]; begin++; while (begin < end) { if (array[end] > compareInt) { end--; continue; } if (array[begin] < compareInt) { begin++; continue; } int tmp = array[begin]; array[begin] = array[end]; array[end] = tmp; } if (array[beginRange] > array[begin]) { int tmp = array[begin]; array[begin] = array[beginRange]; array[beginRange] = tmp; } quick(array, beginRange, begin - 1); quick(array, end + 1, endRange); return; }
3.選擇排序
選擇排序的思想在於每一輪選擇一個本輪的極大值,而後放入數組的尾部。最終可實現排序。數組
public static void selectSort(int[] array) { if (array.length == 0) { return; } for (int i = 0; i < array.length; i++) { int min = array[i]; int minIndex = i; for (int j = i; j < array.length; j++) { if (array[j] < min) { min = array[j]; minIndex = j; } } int tmp = array[i]; array[i] = min; array[minIndex] = tmp; } }
4.歸併排序
歸併排序的思想在於先排序小的數組,再由小的數組合併成大數組,直到最後合併的數組大小是原數組的大小時,即完成了歸併排序。架構
public static void sort(int[] array, int left, int right) { //1.設置遞歸的base case if (left == right) { return; } //2.分別排兩邊 int mid = left + (right - left) / 2; sort(array, left, mid); sort(array, mid + 1, right); //3.合併 merge(array, left, mid + 1, right); } public static void merge(int[] array, int leftPtr, int rightPtr, int rightBound) { int mid = rightPtr - 1; int[] temp = new int[rightBound - leftPtr + 1]; int i = leftPtr, j = rightPtr, k = 0; while (i <= mid && j <= rightBound) { temp[k++] = array[i] <= array[j] ? array[i++] : array[j++]; } while (i <= mid) { temp[k++] = array[i++]; } while (j <= rightBound) { temp[k++] = array[j++]; } //不要忘了把temp數組複製到arr中 for (int m = 0; m < temp.length; m++) { array[leftPtr + m] = temp[m]; } }
5.桶排序
桶排序的思想在於,根據數組中的最大值和最小值的差值做爲區間拆分爲N個桶,將元素落入這些桶當中,進行排序再合併。ui
public static void bucketSort(int[] array){ int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i = 0; i < array.length; i++){ max = Math.max(max, array[i]); min = Math.min(min, array[i]); } //桶數 int bucketNum = (max - min) / array.length + 1; ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum); for(int i = 0; i < bucketNum; i++){ bucketArr.add(new ArrayList<Integer>()); } //將每一個元素放入桶 for(int i = 0; i < array.length; i++){ int num = (array[i] - min) / (array.length); bucketArr.get(num).add(array[i]); } //對每一個桶進行排序 for(int i = 0; i < bucketArr.size(); i++){ Collections.sort(bucketArr.get(i)); } int k = 0; for (int i = 0; i < bucketArr.size(); i++) { for (Integer integer : bucketArr.get(i)) { array[k++] = integer; } } }
6.計數排序
計數排序爲特殊的桶排序,一個桶的值區間爲1。url
public static int[] countSort(int[] array) { if (array == null || array.length == 0) { return null; } int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; //找出數組中的最大最小值 for (int i = 0; i < array.length; i++) { max = Math.max(max, array[i]); min = Math.min(min, array[i]); } int help[] = new int[max]; //找出每一個數字出現的次數 for (int i = 0; i < array.length; i++) { int mapPos = array[i] - min; help[mapPos]++; } int index = 0; for (int i = 0; i < help.length; i++) { while (help[i]-- > 0) { array[index++] = i + min; } } return array; }
7.希爾排序
希爾排序的思想在於步長。先讓元素從數組的一半做爲步長,進行比較替換,再依次減少步長,當步長爲0時,即完成排序。它主要的優點是避免冒泡排序每次交換步長爲1的低效率。.net
public static void shellSort(int[] arr) { //step:步長 for (int step = arr.length / 2; step > 0; step /= 2) { //對一個步長區間進行比較 [step,arr.length) for (int i = step; i < arr.length; i++) { int value = arr[i]; int j; //對步長區間中具體的元素進行比較 for (j = i - step; j >= 0 && arr[j] > value; j -= step) { //j爲左區間的取值,j+step爲右區間與左區間的對應值。 arr[j + step] = arr[j]; } //此時step爲一個負數,[j + step]爲左區間上的初始交換值 arr[j + step] = value; } } }
筆者我的總結,若有錯誤之處望不吝指出。
本文轉自個人我的博客:《CoderV的進階筆記》
歡迎加入Java後端架構技術討論羣:1398880
個人公衆號:CoderV的進階筆記,記錄技術心得
code