---
tags: 演算法, LeetCode
disqus: HackMD
---
# 快速排序(Quick Sort)
## 介紹
> 快速排序是一種分治算法(Divide and Conquer),它將原問題劃分為兩個子問題,一個是比基準值小的數,另一個是比基準值大的數。然後遞歸地解決這兩個子問題,最終得到排序後的結果。

(圖片來自[data_structures_algorithms](https://www.tutorialspoint.com/data_structures_algorithms/quick_sort_algorithm.htm))
## 虛擬碼
運用了分治法的概念,將大的數值移到左邊,小的數值移到右邊,再遞迴運算左右兩側的數值,直到最終整個數列有序
```pseudocode=
QUICK-SORT(p, r):
if p < r:
q = partition(p, r)
QUICK-SORT(p, q - 1)
QUICK-SORT(q + 1, r)
// when calling QUICK-SORT first time, just pass 0 and array.length - 1 as parameters
```
基準值(pivot)並進行數值交換,使得數列的左半部分都小於等於基準值,右半部分都大於等於基準值。最後返回基準值的位置。
```pseudocode=
partition(p, r):
x = A[r] // 基準值pivot
i = p - 1
for j from p to r-1(inclusive):
if A[j] <= x:
i = i + 1
exchange A[i] with A[j]
exchange A[i + 1] with A[r]
return i + 1
```
## 程式碼
```javascript=
let arr = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7];
function partition(p, r){
let x = arr[r];
let i = p - 1;
for (let index = p; index <= r - 1; index++) {
if(arr[index] <= x){
i = i + 1;
[arr[i], arr[index]] = [arr[index], arr[i]];
}
}
[arr[i + 1], arr[r]] = [arr[r], arr[i + 1]];
return i + 1;
}
function quickSort(p , r){
if (p < r){
let q = partition(p, r);
quickSort(p, q - 1);
quickSort(q + 1, r);
}
}
quickSort(0, arr.length - 1)
console.log(arr) // [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]
```
## 複雜度
### 時間複雜度
平均為:
$O(n log n)$
最壞情況每次都選到最小值當作基準值:
$O(n^2)$
### 空間複雜度
$O(log n)$
## 實戰
### 題目說明
[912. Sort an Array](https://leetcode.com/problems/sort-an-array/description/)
給你一個整數陣列`nums`,請將陣列以升序排列並返回。您必須在`O(nlog(n))`時間複雜度內解決此問題,並使用較小的空間複雜度。

### 解法
```javascript=
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
return quickSort(nums)
};
function partition(nums, p, r){
let x = nums[r];
let i = p - 1;
function swap(array, i, j) {
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
for (let index = p; index <= r - 1; index++) {
if(nums[index] <= x){
i = i + 1;
swap(nums, index, i)
}
}
swap(nums, r, i + 1)
return i + 1;
}
function quickSort(nums, p = 0 , r = nums.length - 1){
if (p < r){
let q = partition(nums, p, r);
quickSort(nums, p, q - 1);
quickSort(nums, q + 1, r);
}
return nums
}
```