---
# System prepended metadata

title: 快速排序 (Quick sort)

---

# 快速排序 (Quick sort)

## 簡介
快速排序是對泡沫排序的一種改進。通過一輪排序將要排序的數據分割成獨立的兩部分，其中一部分的數據都比另外一部分的數據要小，然後再按此方法對這兩部分數據分別進行快速排序，整個排序過程可以遞迴進行，以此達到整個數據變成有序。

## 基本思想

1. 先從陣列中取出一個數作為基準數。
2. 以基準數做分區，將比基準數大的數放到它的右邊，小於或等於它的數全放到它的左邊。
3. 再對左右區間重複第二步，直到各區間只有一個數。 

## 算法

**一、設有一組數據 `[2,10,5,11,34,28,21]` 使用快速排序法由小到大排序**

其過程為：

![](https://i.imgur.com/w0RxiR1.png)

上面的例子使用圖解，下面的例子用文字敘述。

**二、使用快速排序法將陣列 [19,97,9,17,1,8] 由小到大排序**

1. 首先我們需要有 i , j 兩個索引
2. 暫定陣列第一個值，也就是 19 為基準值
3. i 索引由 0 開始由左至右移動，j 索引由 陣列最末尾開始由右至左移動 [19(i), 97, 9, 17, 1, 8(j)]
4. 因為我們是將基準值設為左邊第一個，因此我們比較要從最末尾開始比較。
這個陣列的最末尾為 8，將之與基準值 19 做比較，如果比基準值小，放置於i位置，如果比基準值大則不動。8 < 19，因此 8 要放到 i 位置，此時 i+1 進行下一位數比較。
此時陣列為 [8, 97(i), 9, 17, 1, 19(j)]
5. 此時 i 指向的數為 97，與基準值比較 97 > 19，因此將 97放到 j 位置，此時 j-1，繼續下一位比較。此時陣列為 [8, 19(i), 9, 17, 1(j), 97]
6. 此時 j 指向 1，與基準值比較 1 < 19，因此要將 1 放到 i 位置，然後 i+1繼續進行下一個比較。此時陣列為 [8, 1, 9(i), 17, 19(j), 97]
7. 此時 i 指向 9，與基準值比較 9 < 19，因此9要放到左邊，但9本來就在左邊，所以不用動，但是要記得 i+1 指向下一個數比較。此時陣列還是 [8, 1, 9, 17(i), 19(j), 97]
8. 此時 i 指向 17，與基準值比較 17 < 19，因此依然不動，還是一樣 i+1 指向下一個位置，此時陣列還是 [8, 1, 9, 17, 19(i,j), 97]。
9. 直到此刻，i索引和j索引重疊，指向同一個位置，即將基準值 19 擺在重疊的位置，完成排序。

但是我們能發現 [8, 1, 9, 17, 19, 97] 其實還並沒有完成由小到大排序，我們需要再對基準值左右子序列再繼續以上步驟排序，這邊比基準值 19 小的左子序列為 [8, 1, 9, 17]，右子序列為[97]，只剩下一個數的序列已然排序，所以我們只需要再對左子序列進行以上步驟排序。

最終得到排序後的陣列為 [1, 8, 9, 17, 19, 97]。

### 優化

#### Middle-of-Three
1. 令 middle = (left + right) /2
2. 比較 A[left]、A[middle] 與 A[right] 這三筆資料，排出中間值。
3. 將此中間值再與 A[left] 做交換
4. 讓現在新的 A[left] 作為 pivot

#### 詳細請參考
- [Worse case 改進](https://kopu.chat/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F-quick-sort/#lwptoc4)


## 參考資料
- [quick sort geeksforgeeks](https://www.geeksforgeeks.org/quick-sort/)
- [Ithome 詳解](https://ithelp.ithome.com.tw/articles/10202330?sc=iThelpR)