快速排序(Quick Sort)
快速排序的基本思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。
算法描述
快速排序使用分治法來把一個串(list)分為兩個子串(sub-lists)。具體算法描述如下:
-
從數列中挑出一個元素,稱為 “基准”(pivot);
-
重新排序數列,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的后面(相同的數可以到任一邊)。在這個分區退出之后,該基准就處於數列的中間位置。這個稱為分區(partition)操作;
-
遞歸地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序。
代碼實現
import java.util.Arrays;
public class TestQuickSort {
private static int partition(int[] arr, int low, int high) {
//指定左指針i和右指針j
int i = low;
int j= high;
//將第一個數作為基准值。挖坑
int x = arr[low];
//使用循環實現分區操作
while(i<j){//5 8
//1.從右向左移動j,找到第一個小於基准值的值 arr[j]
while(arr[j]>=x && i<j){
j--;
}
//2.將右側找到小於基准數的值加入到左邊的(坑)位置, 左指針想中間移動一個位置i++
if(i<j){
arr[i] = arr[j];
i++;
}
//3.從左向右移動i,找到第一個大於等於基准值的值 arr[i]
while(arr[i]<x && i<j){
i++;
}
//4.將左側找到的打印等於基准值的值加入到右邊的坑中,右指針向中間移動一個位置 j--
if(i<j){
arr[j] = arr[i];
j--;
}
}
//使用基准值填坑,這就是基准值的最終位置
arr[i] = x;//arr[j] = y;
//返回基准值的位置索引
return i; //return j;
}
private static void quickSort(int[] arr, int low, int high) {//???遞歸何時結束
if(low < high){
//分區操作,將一個數組分成兩個分區,返回分區界限索引
int index = partition(arr,low,high);
//對左分區進行快排
quickSort(arr,low,index-1);
//對右分區進行快排
quickSort(arr,index+1,high);
}
}
public static void quickSort(int[] arr) {
int low = 0;
int high = arr.length-1;
quickSort(arr,low,high);
}
public static void main(String[] args) {
//給出無序數組
int arr[] = {72,6,57,88,60,42,83,73,48,85};
//輸出無序數組
System.out.println(Arrays.toString(arr));
//快速排序
quickSort(arr);
//partition(arr,0,arr.length-1);
//輸出有序數組
System.out.println(Arrays.toString(arr));
}
}
最佳情況:T(n) = O(nlogn) 最差情況:T(n) = O(n2) 平均情況:T(n) = O(nlogn)