1、快速排序的原理
選擇一個關鍵值作爲基準值,比基準值小的都在左邊序列(仍是無序的),比基準值大的都在右邊序列(也是無序的),基準值的選取:一般爲第一個元素。
第一次循環:先從後往前比較,用基準值和最後一個值比較,如果比基準值小的交換位置。如果沒有就繼續比較下一個,直到找到第一個比基準值小的值才交換。 找到這個值之後,就從前往後開始比較,如果有比基準值大的,交換位置,沒有就繼續比較下一個,直到找到第一個比基準值大的值才交換。第一次 循環結束條件 :從前往後的索引指針>從後往前的索引指針,然後遞歸排序前後兩段‘子組’。
2、動圖實現快排
3、具體實現代碼:
import java.util.Arrays;
public class QuickSortDemo {
public static void main(String[] args) {
int[] num = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
System.out.println("未排序:" + Arrays.toString(num));
quickSort(num, 0, num.length - 1);
System.out.println("排序後:" + Arrays.toString(num));
}
public static void quickSort(int[] arr, int start, int end) {
if (arr == null || start >= end) return;
int i = start, j = end;
int pivotKey = arr[start]; // 用子表的第一個記錄做基準
// 從表的兩端交替向中間掃描
while (i < j) {
// 順序很重要,要先從右邊開始找
while (i < j && arr[j] >= pivotKey) j--;
if (i < j) arr[i++] = arr[j]; //用比基準小的記錄替換低位記錄
while (i < j && arr[i] <= pivotKey) i++;
if (i < j) arr[j--] = arr[i]; // 用比基準大的記錄替換高位記錄
}
arr[i] = pivotKey; // 將基準數值替換回 arr[i]
quickSort(arr, start, i - 1); // 遞歸排序比開始時基準數低的'子數組'
quickSort(arr, i + 1, end); // 遞歸排序比開始時基準數高的'子數組'
}
}
排序結果:
4、複雜度分析:
(1)時間複雜度
① 最好和平均時間複雜度
最好情況是指選擇的基準關鍵字爲待排序的記錄的中間值。此時進行比較次數總共爲 nlogn,所以最好情況下快速排序的時間複雜度爲O(nlogn)。
快速排序的平均時間複雜度爲O(nlogn)。
在所有平均時間複雜度爲O(nlogn)的算法中,快速排序的平均性能是最好的。
② 最壞時間複雜度
最壞情況是指每次區間劃分的結果都是基準關鍵字的左邊(或右邊)序列爲空,而另一邊區間中的記錄僅比排序前少了一項,即選擇的關鍵字是待排序記錄的最小值或最大值。最壞情況下快速排序的時間複雜度爲O(n^2)。
(2)空間複雜度
快速排序的過程中需要一個棧空間來實現遞歸。最好情況遞歸樹的深度爲log2n,其空間複雜度也就是O(nlogn);平均情況空間複雜度爲O(nlogn);最壞情況下,需要進行 n-1次遞歸,其空間複雜度爲O(n)。