快速排序是一種基於交換的高效排序算法,它採用了分治法的思想。步驟以下:算法
快排最重要的步驟就是劃分了(Partition)。劃分的過程用通俗的語言講就是「挖坑」和「填坑」。數組
圖片較小,請原諒優化
int partition(int arr[], int left, int right) //找基準數進行劃分 { int low = left + 1; //區間下端 int high = right; //區間上端 int pivot = left; //樞軸下標 int cur = pivot+1; //存儲位置下標 for(int i=low; i<=high; i++) //從下端到上端的遍歷 { if(arr[i] < arr[pivot]) { swap(arr[i], arr[cur]); //交換如今的值和存儲位置的值 cur++; //將存儲位置變爲下一位 } } swap(arr[pivot], arr[cur-1]); //將樞軸移至數組正確位置 return cur-1; //返回樞軸位置 } void quick_sort(int arr[], int left, int right) { if (left >= right) return; int mid = partition(arr, left, right); //獲取樞軸位置 quick_sort(arr, left, mid - 1); //下端區間遞歸 quick_sort(arr, mid + 1, right); //上端區間遞歸 }
快排的時間複雜度在最壞狀況下是 O(n²),平均的時間複雜度是 O(n log n)。ui
怎麼理解呢?其實很簡單。假設數列中有n個數,則遍歷一次的時間複雜度爲 O(n),須要遍歷至少 log (n + 1)次,最多 n次。.net
+Q1:爲何最少是 log (n + 1)次?
+A1:快速排序是採用分治法進行遍歷的,因此能夠當作一棵二叉樹,它遍歷的次數就是二叉樹的深度。而根據二叉樹的定義,它的深度至少爲 log (n + 1)。所以快速排序的遍歷次數至少是 log (n + 1)次。code
+Q2:爲何最可能是 n次遍歷?
+A2:這個應該比較好理解。仍然將快速排序看做一棵二叉樹,二叉樹的最大深度爲 n。因此快速排序的遍歷次數最可能是 n次。blog
快速排序是不穩定的算法,它不知足穩定排序算法的定義。 算法穩定性:假設在數列中存在 a[i] = a[j],若在排序以前,a[i] 在 a[j] 前面,而且排序後,a[i]仍然在 a[j]前面,則這個排序是穩定的!排序
快速排序優化已更新!傳送門遞歸