原文地址:xeblog.cn/articles/17數組
快速排序使用的是
分治思想
,經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。bash
k
,通常取數組第一個元素,以此值分割數組;i
和 j
,i
指向數組的最低位
,j
指向數組的最高位
;j
開始從數組最高位
往數組最低位
(j--)掃描比 k
小的值,掃描到後中止掃描,並將該值填入 i
所處的位置,而後再由 i
開始從數組最低位
往數組最高位
(i++)掃描比 k
大的值,掃描到後中止掃描,並將該值填入 j
所處的位置,j
和 i
依次掃描,直至 j
與 i
的位置相互重合後,將 k
的值填入重合處,此時,數組左側的值均小於 k
,右側值均大於 k
,完成這次排序;演示圖 測試
/** * 快速排序 * @param array 待排序數組 * @param begin 起點索引 * @param end 終點索引 */
private static void fastSort(int[] array, int begin, int end) {
// 遞歸終止條件,起點索引大於等於終點索引
if (begin >= end) {
return;
}
// 起點索引
int i = begin;
// 終點索引
int j = end;
// 基準值
int k = array[begin];
// 循環條件:起點索引小於終點索引
while (i < j) {
/* 這個循環是要掃描小於基準值的值,掃描到後退出循環, 循環條件:當前索引位的值大於等於基準值k(加等於號是防止相同數字交換而陷入死循環中), 且起點索引小於終點索引(防止數組下標出界) */
while (array[j] >= k && i < j) {
// 終點索引位從右至左逐個遞減
j--;
}
if (i < j) {
// 將小於基準值的數移至左側
array[i] = array[j];
}
/* 這個循環是要掃描大於基準值的值,掃描到後退出循環, 循環條件:當前索引位的值小於等於基準值k(加等於號是防止相同數字交換而陷入死循環中), 且起點索引小於終點索引(防止數組下標出界) */
while (array[i] <= k && i < j) {
// 起點索引位從左至右逐個遞增
i++;
}
if (i < j) {
// 將大於基準值的數移至右側
array[j] = array[i];
}
}
if (array[j] != k) {
// 基準值歸位(數組的中間某個位置),歸位後,基準值左側都是小於基準值的數,右側都是大於基準值的數
array[j] = k;
}
// 遞歸將基準值左側的數排序
fastSort(array, begin, j - 1);
// 遞歸將基準值右側的數排序
fastSort(array, j + 1, end);
}
複製代碼
測試排序spa
int[] array = {5, 6, 6, 4, 3, 5, 5};
System.out.println("排序前:" + Arrays.toString(array));
fastSort(array, 0, array.length - 1);
System.out.println("排序後:" + Arrays.toString(array));
複製代碼
輸出結果code
排序前:[5, 6, 6, 4, 3, 5, 5]
排序後:[3, 4, 5, 5, 5, 6, 6]
複製代碼
平均時間複雜度: O(nlogn)
。
最壞時間複雜度: O(n^2)
,這種狀況發生在排序數組爲正序
或逆序
的時候。
穩定性: 不穩定。cdn