# 快速排序法 QuickSort
###### tags: `leetcode`,`sorting`
>ref: https://github.com/chmonk/leetCodeTraining/blob/dev/src/sort/quickSort.java
>
## 基礎流程
1. 利用數列中最前或最後的idx作為pivot(比較基準),由此pivot將該數列分類,理想的pivot為該數列之數值排列中位數(此情況為time resolution為 O(n log~2~n),最差的情形為該數列已經過排序,每次分組取到的pivot皆為該數組之極值,此情況下為 O(n^2^)以上
2. TR, 比較行為為n次(每數組需要跟pivot比較), 依據分組情況最優化為log~2~n組=>O(nlog~2~n), 最差為分組n次(每次分組為極值一個與剩餘情況)=>O(n^2^)
```java=
public void quickSort(int[] nums, int start_idx, int end_idx) {
// termination condition
if (end_idx - start_idx < 1) {
return;
}
//use the last idx as pivot
int pivot = nums[end_idx];
int lower_idx = start_idx;
for (int loop_idx = start_idx; loop_idx < end_idx; loop_idx++) {
//while the number smaller than pivot,replace this num to the lower_idx
if (nums[loop_idx] < pivot) {
swap(nums, lower_idx, loop_idx);
lower_idx++;
}
}
swap(nums, lower_idx, end_idx);
// number array idx lower than lower_idx are smaller than the pivot
quickSort(nums, start_idx, lower_idx - 1);
// number array idx larger than lower_idx are larger than the pivot
quickSort(nums, lower_idx + 1, end_idx);
}
```
```java=
private void swap(int[] nums, int a, int b) {
int record = nums[a];
nums[a] = nums[b];
nums[b] = record;
}
```
## 進階:優化
1. pivot選擇中間數
2. 當數列中有數字與pivot相同時,集中於數列內連續排列,並不進行到下次的子排序
```java=
public void quickSort_dual(int[] nums, int start_idx, int end_idx) {
// termination condition
if (start_idx >= end_idx) {
return;
}
int middle_idx = start_idx + (end_idx - start_idx) / 2; //avoid big number
int pivot_idx = end_idx;
//use the middle value as pivot to separate the array
if (nums[start_idx] > nums[middle_idx]) {
swap(nums, start_idx, middle_idx);
}
if (nums[end_idx] < nums[middle_idx]) {
swap(nums, end_idx, middle_idx);
}
if (nums[start_idx] > nums[middle_idx]) {
swap(nums, start_idx, middle_idx);
}
swap(nums, end_idx, middle_idx);
int low = start_idx;
int high = end_idx - 1; // leave pivot as standard
int loop_idx = start_idx;
while (loop_idx <= high) {
if (nums[loop_idx] < nums[pivot_idx]) {
// < pivot , exchange with the nums[++low] (exchange with the number bigger than
// pivot),loop++
swap(nums, low++, loop_idx++);
} else if (nums[loop_idx] == nums[pivot_idx]) {
// == pivot , loop++
loop_idx++;
} else {
// >pivot exchange with the nums[high] and loop_idx don't ++ for check the
swap(nums, high--, loop_idx);
}
}
swap(nums, ++high, pivot_idx); // put the pivot value in the middle
quickSort_dual(nums, start_idx, --low); //owing to low++, in the end, now the low idx is the pivot value, so --low
quickSort_dual(nums, ++high, end_idx); // in the end, high idx is the pivot, ++high lead to high point to the number larger than pivot
}
```