---
# System prepended metadata

title: 快速排序法 QuickSort
tags: [leetcode, sorting]

---


# 快速排序法 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

	}

```