概念:
快速排序是對冒泡排序的一種改進。由C.A.R.Hoare於1962年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
排序過程:
假設要排序的數組是A[0]..A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作為關鍵數據,然后將所有比它小的數都放到它的前面,所有比它大的數據都放到它的后面,這個過程稱為一趟快速排序。值得注意的是:快速排序不是一種穩定的排序算法,也就是說,多個相同的值的相對位置也許會在算法結束時產生變動。
一趟快速排序的算法是:
1.設置兩個變量i、j,排序開始時:i=0; j=N-1;
2.以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];
3.從j開始向前檢索,即由后向前開始檢索(j--),找到第一個小於key的值A[j],將A[j]和A[i]互換;
4.從i開始向后檢索,即由前向后開始檢索(i++),找到第一個大於key的A[i],將A[i]和A[j]互換;
5.重復第3、4步,直到i=j;(3、4步中,沒找到符合條件的值,即第3步中A[j]不小於key,第4步中A[i]不大於key時改變i、j的值,使得j=j-1; i=i+1; 直至找到該值為止。找到符合條件的值,進行交換的時候i和j的指針位置不變。另外,i==j這一過程一定正好是i++或j--完成的時候,此時令循環結束)
示例:
package com.cnblogs.lxj.testarraysort;
/**
* @author liuxiaojiang
* @packageName:com.cnblogs.lxj.testarraysort
* @ClassName:QuickSort
* @Description:測試快速排序
* @date 2020/11/30
*/
public class QuickSort {
/**
* 主方法
* @param args
*/
public static void main(String[] args) {
int[] a = {5,1,9,3,7,4,8,6,2};
printArray(a);
quickSort(0,a.length - 1,a);
printArray(a);
}
/**
* 快速排序方法
* @param low
* @param high
* @param a
*/
public static void quickSort(int low,int high,int[] a){
if(low < high){
int middle = getMiddle(low,high,a);
quickSort(low,middle - 1,a);
quickSort(middle + 1,high,a);
}
}
/**
* 邏輯算法
* @param low
* @param high
* @param a
* @return
*/
public static int getMiddle(int low,int high,int[] a){
int temp = a[low];
while(low < high){
while(a[high] >= temp && low < high){
high--;
}
a[low] = a[high];
low++;
while(a[low] <= temp && low < high){
low++;
}
a[high] = a[low];
}
a[high] = temp;
return high;
}
/**
* 輸出方法
* @param array
*/
public static void printArray(int[] array){
for(int a : array){
System.out.print(a + " ");
}
System.out.println();
}
}
運行結果:
5 1 9 3 7 4 8 6 2 //初始化
1 2 3 4 5 6 7 8 9 //快速排序完成
原理:
算法分析:
快速排序可以說是數組排序中性能最好的排序算法,但它是不穩定的算法,比如當同一數組中有兩個(或多個)值相同的元素時,排序完成后,該多個元素位置(順序)可能會發生改變。快速排序主要有兩個基本操作:一是選取樞軸元素,另一個則是遞歸分割數組。樞軸元素的選取對快速排序的效率至關重要,因為它決定了遞歸的深度。如果樞軸元素剛好處於數組的中間值,那么,數組在分割時就分成了平均的兩部分。這樣的遞歸的效率就好。如果每次選取的樞軸元素都是最大/最小 的那個元素,則快排復雜度達到了O(N2),而且還用了遞歸棧空間。快速排序的時間復雜度與樞軸元素的選取息息相關。平均情況下,時間復雜度為O(NlogN),最壞情況下為O(N2)。所以,快速排序更適合數據量比較大時使用。(另:需要注意,當選取數組元素中的最小值作為樞軸且要降序時,這時候的執行時間巨長,所以,在使用時需要根據實際情況調整)