1. 快排的思想
通過一趟排序將要排序的數據分割成獨立的兩部分,前一部分的所有數據都要小於后一部分的所有數據,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據的有序性。
2. 快排實現的核心步驟
①找基准點:一般是數組的第一個元素來充當;
②right:從數組的最后一個元素開始,從右往左,直到找到小於基准點的元素;每次都要right比left先走;
③left:從數組的第一個元素開始,從左往右,直到找到大於基准點的元素;
④交換 left 和 right 所在位置的兩個元素;
⑥right 繼續往左走,找到小於基准點的元素;left 繼續往右走,找到大於基准點的元素;然后 left 和 right 再做交換;循環往復,直到兩人相遇;
⑦將相遇點所在位置的元素和基准點所在位置的元素做交換,基准點到了中間位置(此時基准點左邊的元素全都小於基准點右邊的元素);
⑧【遞歸】將基准點左邊的所有元素當成一個數組,重復①~⑦步驟;基准點右邊的所有元素也是如此;
3. 快排的java代碼實現
1 public class A01QuickSort { 2 public static void main(String[] args) { 3 A01QuickSort quickSort = new A01QuickSort(); 5 6 // 測試快排的效率: 7 // int number = 1000000; 8 // int[] array = new int[number]; 9 // for (int i = 0; i < array.length; i++) { 10 // array[i] = new Random().nextInt(number); 11 // } 12 13 //配合后面的元素輸出,測試快排是否排序准確: 14 int[] array = new int[] {181,181,187,181}; 15 System.out.println("數組准備完畢~"); 16 17 long start = System.currentTimeMillis(); 18 quickSort.quickSort(array, 0, array.length - 1); 19 long end = System.currentTimeMillis(); 20 System.out.println("quickSort 用時:" + (end - start));// 測試結果: 元素為5萬個時:11毫秒。50萬:66毫秒。100萬:136毫秒 21 22 //遍歷輸出數組元素: 23 quickSort.traverseArray(array); 24 } 25 26 /** 27 * 快排的實現 28 * @param target 29 * @param left 30 * @param right 31 */ 32 public void quickSort(int[] target, int left, int right) { 33 if (left >= right) { 34 return; 35 } 36 int pivot = target[left];// 基准點 37 int temp; 38 int i = left; 39 int j = right;//為什么要聲明i和j,因為后面做迭代的時候還需要用到最初的left和right 40 while (i < j) {//驗證array數組至少有2個元素,才要做排序 41 /** 42 * 提問: 43 * 為什么是 while里的判斷,為什么是 “target[j] >= pivot”,而不是“target[j] > pivot”??? 44 * 答: 數組[181,181,187,181],分別用上面兩種while去測試: 45 * 如果是">="時,因為 181 >= 181 成立,所以right就會從右往左移; 46 * 如果是">"時,因為 181 > 181 成立,所以right就不會左移。 47 * 重點!!!right或left,必須有一方得是移動的!!!否則程序就會進入死循環!!! 48 */ 49 // 如果right一直都大於或等於pivot,則繼續走,直到找到比pivot小的: 50 while (target[j] >= pivot && i < j) { 51 j--; 52 } 53 // 如果left一直都小於等於pivot,則繼續走,直到找到比pivot大的: 54 while (target[i] <= pivot && i < j) { 55 i++; 56 } 57 // 此時right < pivot, left > pivot,將i和j做交換: 58 if (i < j) {//這里做判斷是為了right到了left位置時,不用再將執行下面這三行代碼了: 59 temp = target[i]; 60 target[i] = target[j]; 61 target[j] = temp; 62 } 63 } 64 // left和right相遇了: 65 // ①將相遇點的元素和pivot做交換: 66 target[left] = target[j]; 67 target[j] = pivot; 68 // ②基准點兩邊的元素的分別再做排序: 69 quickSort(target, left, j - 1); 70 quickSort(target, j + 1, right); 71 } 72 73 //遍歷數組 74 public void traverseArray(int[] array) { 75 for(int element : array) { 76 System.out.println(element); 77 } 78 } 79 }
4. 快排的時間復雜度:O(n * log(n))
快排的時間復雜度分析:快排的時間復雜度分析(含圖解)