基於Java實現的快速排序


簡述

快速排序是一種排序執行效率很高的排序算法,它利用分治法來對待排序序列進行分治排序,它的思想主要是通過一趟排序將待排記錄分隔成獨立的兩部分,其中的一部分比關鍵字小,后面一部分比關鍵字大,然后再對這前后的兩部分分別采用這種方式進行排序,通過遞歸的運算最終達到整個序列有序,下面我們簡單進行闡述。

快排思路

我們從一個數組來逐步逐步說明快速排序的方法和思路。

  1. 假設我們對數組{7, 1, 3, 5, 13, 9, 3, 6, 11}進行快速排序。
  2. 首先在這個序列中找一個數作為基准數,為了方便可以取第一個數。
  3. 遍歷數組,將小於基准數的放置於基准數左邊,大於基准數的放置於基准數右邊
  4. 此時得到類似於這種排序的數組{3, 1, 3, 5, 6, 7, 9, 13, 11}。
  5. 在初始狀態下7是第一個位置,現在需要把7挪到中間的某個位置k,也即k位置是兩邊數的分界點。
  6. 那如何做到把小於和大於基准數7的值分別放置於兩邊呢,我們采用雙指針法從數組的兩端分別進行比對
  7. 先從最右位置往左開始找直到找到一個小於基准數的值,記錄下該值的位置(記作 i)。
  8. 再從最左位置往右找直到找到一個大於基准數的值,記錄下該值的位置(記作 j)。
  9. 如果位置i<j,則交換i和j兩個位置上的值,然后繼續從(j-1)的位置往前(i+1)的位置往后重復上面比對基准數然后交換的步驟。
  10. 如果執行到i==j,表示本次比對已經結束,將最后i的位置的值與基准數做交換,此時基准數就找到了臨界點的位置k,位置k兩邊的數組都比當前位置k上的基准值或都更小或都更大。
  11. 上一次的基准值7已經把數組分為了兩半,基准值7算是已歸位(找到排序后的位置)
  12. 通過相同的排序思想,分別對7兩邊的數組進行快速排序,左邊對[left, k-1]子數組排序,右邊則是[k+1, right]子數組排序
  13. 利用遞歸算法,對分治后的子數組進行排序。

快速排序之所以比較快,是因為相比冒泡排序,每次的交換都是跳躍式的,每次設置一個基准值,將小於基准值的都交換到左邊,大於基准值的都交換到右邊,這樣不會像冒泡一樣每次都只交換相鄰的兩個數,因此比較和交換的此數都變少了,速度自然更高。當然,也有可能出現最壞的情況,就是仍可能相鄰的兩個數進行交換。

快速排序基於分治思想,它的時間平均復雜度很容易計算得到為O(NlogN)。

代碼實現

 1 /**
 2  * 快速排序
 3  * @param array
 4  */
 5 public static void quickSort(int[] array) {
 6     int len;
 7     if(array == null
 8             || (len = array.length) == 0
 9             || len == 1) {
10         return ;
11     }
12     sort(array, 0, len - 1);
13 }
14 
15 /**
16  * 快排核心算法,遞歸實現
17  * @param array
18  * @param left
19  * @param right
20  */
21 public static void sort(int[] array, int left, int right) {
22     if(left > right) {
23         return;
24     }
25     // base中存放基准數
26     int base = array[left];
27     int i = left, j = right;
28     while(i != j) {
29         // 順序很重要,先從右邊開始往左找,直到找到比base值小的數
30         while(array[j] >= base && i < j) {
31             j--;
32         }
33 
34         // 再從左往右邊找,直到找到比base值大的數
35         while(array[i] <= base && i < j) {
36             i++;
37         }
38 
39         // 上面的循環結束表示找到了位置或者(i>=j)了,交換兩個數在數組中的位置
40         if(i < j) {
41             int tmp = array[i];
42             array[i] = array[j];
43             array[j] = tmp;
44         }
45     }
46 
47     // 將基准數放到中間的位置(基准數歸位)
48     array[left] = array[i];
49     array[i] = base;
50 
51     // 遞歸,繼續向基准的左右兩邊執行和上面同樣的操作
52     // i的索引處為上面已確定好的基准值的位置,無需再處理
53     sort(array, left, i - 1);
54     sort(array, i + 1, right);
55 }

參考資料

1、《啊哈!算法》/ 啊哈磊著. 人民郵電出版社


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM