快速排序(Quicksort),又稱劃分交換排序(partition-exchange sort),簡稱快排,最先由東尼·霍爾提出,是一種較快的排序算法。對n項進行排序平均要作O(nlog<sub>n</sub>)次比較,最差的狀況下須要作O(n<sup>2</sup>)次比較。本文將介紹快速排序的基本思想及其實現。 ##基本思想 它採用了一種分治的策略,一般稱其爲分治法(Divide-and-ConquerMethod)。排序的過程是一個不斷挖坑、填坑的過程。java
- 首先選取一個基準點(Base),此時基準點所在位置就是一個坑;
- 從右往左找到比基準點小的數字,在該位置挖出一個坑並將該數字放入左邊的坑;
- 從左邊的坑開始,從左往右找出比基準點大的數字,在該位置挖出一個坑並將該數字放入第二步中在右邊的坑;
- 重複第二步和第三步,直到左右兩邊的坑重疊,將基準點放入該坑;
- 此時基準點已經將數組分紅了兩個區:左邊的區、右邊的區。而後在左右兩邊在執行1,2,3,4,5的操做,直到分區中只有一個數字。
假設咱們要對10 22 78 6 1 12 14 45
進行排序,首先取第一個數(10)做爲基準點:算法
- 初始狀態:base = 10(紅色的字體的數字表示基準點)
- 從右往左找比基準點(10)小的數字,發現位於數組中的序號爲4的數字1比基準點(10)小,因而將數字1填入序號爲0的基準點的坑中去。紅色背景色的單元格表示剛被填充過的坑,灰色的背景色表示剛挖出來的坑,下面同理。
- 從左(從序號1開始)往右找比基準點(10)大的數字,發現序號爲1的數字22比基準點大,因而將數字22填入序號爲5的坑中
- 接下來不在累敘上面的步驟,只給出操做: 至此對基準點(10)不能再繼續進行填坑操做,因而將基準點(10)填入最後的坑中,很顯然,基準點(10)已經將該數組分紅了兩部分:
- 基準點(10)分區完成後的結果以下。而後對基準點(10)的左右兩邊(黃色背景部分)再分別執行相同的分區操做直到不能再進行分區,即完成了排序。
- ......
##JAVA代碼實現數組
static void quickSort(int[] arr, int left, int right) { if (left >= right) { return; } int first = left, last = right; int base = arr[first]; while (first < last) { for (; first < last; last--) { if (arr[last] < base) { arr[first++] = arr[last]; break; } } for (; first < last; first++) { if (arr[first] > base) { arr[last--] = arr[first]; break; } } } arr[first] = base; quickSort(arr, left, first - 1); quickSort(arr, first + 1, right); } static void quickSort(int[] arr) { quickSort(arr, 0, arr.length - 1); }
如上的代碼給出了快速排序的基本實現,主要運用到了基本思想中所闡述的實現思想,將上面的例子在代碼中運行:ide
public static void main(String[] args) { int[] arr = new int[] {10, 22, 78, 6, 1, 12, 14, 45}; System.out.println("原始數組:" + Arrays.toString(arr)); quickSort(arr); System.out.println("排序後的數組:" + Arrays.toString(arr)); }
運行結果爲:字體
原始數組:[10, 22, 78, 6, 1, 12, 14, 45] 排序後的數組:[1, 6, 10, 12, 14, 22, 45, 78]
總結
快速排序算法是一種比較常見的排序算法,其排序的過程是不斷挖坑、填坑的過程,而後將待排序數組分區。思考一個問題:假如運氣很差選擇的基準點是整個數組中最大或者最小的數字,那麼會怎麼樣呢?例如這樣的一個數組:1 10 23 6 9 10
,若是選擇數字1做爲基準點,那麼或發生什麼?ui
相關資源
- <a href="https://pan.baidu.com/s/1Z9s86uS3HCIx8ruibJil-w" target="_blank">本文例子源碼下載</a>