交換排序—快速排序(Quick Sort)
基本思想:
1)選擇一個基准元素,通常選擇第一個元素或者最后一個元素,
2)通過一趟排序講待排序的記錄分割成獨立的兩部分,其中一部分記錄的元素值均比基准元素值小。另一部分記錄的 元素值比基准值大。
3)此時基准元素在其排好序后的正確位置
4)然后分別對這兩部分記錄用同樣的方法繼續進行排序,直到整個序列有序。
快速排序的示例:
(a)一趟排序的過程:
快速排序里的挖坑填補法:以49為標准值,從右開始找比49小的值,首先是27,把27放在49的那個位置,把49放在27的位置,在從左找比49大的值65,把65放在49的新位置(原27的位置)之后變成 27,38,49,97,76,13,65.49
在新的一輪開始,從右開始找49 小的數是13,把13放在49的位置,49放在13的位置,在從左找比49大的數97,把97放在49的新位置上(原13的位置)變成27,38,13,49,76,97,65,49
(b)排序的全過程
算法的實現:
1 /** 2 * 3 * @author zhangtao 4 */ 5 public class QuickSort { 6 7 public static void main(String[] args) { 8 int arr[] = {49, 38, 65, 97, 76, 13, 27, 49}; 9 quickSort(arr, 0, arr.length - 1); 10 } 11 12 //打印每次的排序結果 13 static void printLine(int[] arr) { 14 int Arrlength = arr.length; 15 for (int j = 0; j < Arrlength; j++) { 16 System.out.print(arr[j] + " "); 17 } 18 System.out.println(); 19 } 20 21 static int partition(int a[], int low, int high) { 22 int privotKey = a[low]; //基准元素 23 while (low < high) { //從表的兩端交替地向中間掃描 24 while (low < high && a[high] >= privotKey) //從high 所指位置向前搜索,至多到low+1 位置。將比基准元素小的交換到低端 25 { 26 --high; //從右找比基准元小的 27 } 28 a[low] = a[high]; //如果比基准元素小,交換 29 a[high] = privotKey; 30 31 while (low < high && a[low] <= privotKey) { 32 ++low; //從右找比基准元大的 33 } 34 a[high] = a[low]; //如果比基准元素,交換 35 a[low] = privotKey; 36 37 } 38 printLine(a); 39 return low; 40 } 41 //快速排序 42 43 static void quickSort(int a[], int low, int high) { 44 if (low < high) { 45 int privotLoc = partition(a, low, high); //將表一分為二 46 quickSort(a, low, privotLoc - 1); //遞歸對低子表遞歸排序 47 quickSort(a, privotLoc + 1, high); //遞歸對高子表遞歸排序 48 } 49 } 50 }
分析:
快速排序是通常被認為在同數量級(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按關鍵碼有序或基本有序時,快排序反而蛻化為冒泡排序。為改進之,通常以“三者取中法”來選取基准記錄,即將排序區間的兩個端點與中點三個記錄關鍵碼居中的調整為支點記錄。快速排序是一個不穩定的排序方法。