一、快速排序算法
快速排序算法是對冒泡排序的一種改進。
快排基本思想是:通過一趟排序將要排序的數據以基準數據分割成獨立的兩部分,其中一部分的所有數據都比基準數據小,另外一部分的所有數據都比基準數據大,然後再通過遞歸對這兩部分數據分別進行快速排序,實現整個數據變成有序序列。
二、實例排序步驟分析
樣本數據:45 23 68 88 55 12 100 9
- 基準數: 一般取待排序序列的第一個
- 目標: 交換後, 基準數左邊的數要全部小於基準數, 其右邊的數要全部大於基準數
步驟如下: - 第一次排序基準數:45
- 從後往前找到比基準數小的數進行對換,循環找到9小於45,則9和45對換位置,否則右邊下標前移,繼續循環判斷 <-----
9 23 68 88 55 12 100 45 - 從前往後找到比基準數大的進行對換,23小於45,左邊下標後移,繼續循環找到68大於45,則68和45對換位置,否則左邊下標後移,繼續循環判斷 ----->
9 23 45 88 55 12 100 68 - 從後往前找到比基準數小的數進行對換 <-----
9 23 12 88 55 45 100 68 - 從前往後找到比基準數大的進行對換 ----->
9 23 12 45 55 88 100 68 - 至此,以基準數分爲3部分,左邊的都比其小,右邊的都比其大,第一次以45爲基準數的排序完成
{9 23 12} {45} {55 88 100 68}
對於{9 23 12} 和 {55 88 100 68}這兩部分數據再通過遞歸分別進行快速排序。
三、算法實現
實現代碼如下:
/**
* 快速排序算法
*/
public class QuickSort {
public static void main(String[] args) {
int data[] = {45,23,68,88,55,12,100,9};
quickSort(data, 0, data.length-1);
}
private static void quickSort(int[] data, int left, int right){
int base = data[left];
int leftIndex = left; // 記錄當前左邊要找的位置
int rightIndex = right; // 記錄當前右邊要找的位置
while(leftIndex < rightIndex){
// 從隊列後面往前找出比base小的第一個數, 沒有滿足條件的則右邊下標前移,繼續判斷
while(leftIndex < rightIndex && data[rightIndex]>=base){
rightIndex --;
}
// 表示已找到 9
if (leftIndex < rightIndex){
swap(data, leftIndex, rightIndex);
leftIndex ++;
print(data);
}
// 從隊列前面往後找出比base 大的第一個數
while (leftIndex < rightIndex && data[leftIndex] <= base) {
leftIndex++;
}
// 循環2次後,表示已找到 68
if(leftIndex < rightIndex){
swap(data, leftIndex, rightIndex);
rightIndex --;
print(data);
}
}
// print(data);
// 以基準數分爲3部分, 前後部分遞歸排序
if(leftIndex > left){
quickSort(data, left, leftIndex-1);
}
if(rightIndex < right){
quickSort(data, leftIndex+1, right);
}
}
/**
* 對換數據位置
* @param data
* @param leftIndex
* @param rightIndex
*/
private static void swap(int[] data, int leftIndex, int rightIndex) {
int temp = data[rightIndex];
data[rightIndex] = data[leftIndex];
data[leftIndex] = temp;
}
private static void print(int[] data){
for(int i=0,len = data.length; i<len; i++){
System.out.print(data[i]+" ");
}
System.out.println();
}
}
運行結果:
9 23 68 88 55 12 100 45
9 23 45 88 55 12 100 68
9 23 12 88 55 45 100 68
9 23 12 45 55 88 100 68
9 12 23 45 55 88 100 68
9 12 23 45 55 68 100 88
9 12 23 45 55 68 88 100
注: 快速排序的最好的情況(每次數據劃分得很均勻)時間複雜度爲O(nlogn),最壞的情況(需排序的數據爲正序或逆序排列時)複雜度爲O(n^2)。
參考:
圖靈學院趙雲老師-實戰應用Java算法分析與設計公開課