快速排序及最佳化(Java實現)

來源:互聯網
上載者:User

標籤:rand   str   ati   不一致   math   com   ret   lin   實現   

普通快速排序

找一個基準值base,然後一趟排序後讓base左邊的數都小於base,base右邊的數都大於等於base。再分為兩個子數組的排序。如此遞迴下去。

public class QuickSort {    public static <T extends Comparable<? super T>> void sort(T[] arr) {        sort(arr, 0, arr.length - 1);    }    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {        if (left >= right) return;        int p = partition(arr, left, right);        sort(arr, left, p - 1);        sort(arr, p + 1, right);    }    private static <T extends Comparable<? super T>> int partition(T[] arr, int left, int right) {        T base = arr[left];        int j = left;        for (int i = left + 1; i <= right; i++) {            if (base.compareTo(arr[i]) > 0) {                j++;                swap(arr, j, i);            }        }        swap(arr, left, j);        return j;//返回一躺排序後基準值的下角標    }    public static void swap(Object[] arr, int i, int j) {        if (i != j) {            Object temp = arr[i];            arr[i] = arr[j];            arr[j] = temp;        }    }    private static void printArr(Object[] arr) {        for (Object o : arr) {            System.out.print(o);            System.out.print("\t");        }        System.out.println();    }    public static void main(String args[]) {        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};        printArr(arr);//3   5   1   7   2   9   8   0   4   6        sort(arr);        printArr(arr);//0   1   2   3   4   5   6   7   8   9    }}

  

快速排序最佳化:

在數組幾乎有序時,快排效能不好(因為每趟排序後,左右兩個子遞迴規模相差懸殊,大的那部分最後很可能會達到O(n^2))。

解決:基準值隨機地選取,而不是每次都取第一個數。這樣就不會受“幾乎有序的數組”的幹擾了。但是對“幾乎亂序的數組”的排序效能可能會稍微下降,至少多了排序前交換的那部分,亂序時這個交換沒有意義...有很多“運氣”成分..

public class QuickSort {    public static <T extends Comparable<? super T>> void sort(T[] arr) {        sort(arr, 0, arr.length - 1);    }    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {        if (left >= right) return;        int p = partition(arr, left, right);        sort(arr, left, p - 1);        sort(arr, p + 1, right);    }    private static <T extends Comparable<? super T>> int partition(T[] arr, int left, int right) {        //排序前,先讓基準值和隨機的一個數進行交換。這樣,基準值就有隨機性。        //就不至於在數組相對有序時,導致左右兩邊的遞迴規模不一致,產生最壞時間複雜度        swap(arr,left,(int)(Math.random()*(right - left + 1)+left));        T base = arr[left];        int j = left;        for (int i = left + 1; i <= right; i++) {            if (base.compareTo(arr[i]) > 0) {                j++;                swap(arr, j, i);            }        }        swap(arr, left, j);        return j;//返回一躺排序後,基準值的下角標    }    public static void swap(Object[] arr, int i, int j) {        if (i != j) {            Object temp = arr[i];            arr[i] = arr[j];            arr[j] = temp;        }    }    private static void printArr(Object[] arr) {        for (Object o : arr) {            System.out.print(o);            System.out.print("\t");        }        System.out.println();    }    public static void main(String args[]) {        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};        printArr(arr);//3   5   1   7   2   9   8   0   4   6        sort(arr);        printArr(arr);//0   1   2   3   4   5   6   7   8   9    }}

  

快速排序繼續最佳化:

快排是不斷減小問題規模來解決子問題的,需要不斷遞迴。但是遞迴到規模足夠小時,如果繼續採用這種 不穩定+遞迴 的方式執行下去,效率不見得會很好。

所以當問題規模較小時,近乎有序時,插入排序表現的很好。Java內建的Arrays.sort()裡經常能看到這樣的注釋:“Use insertion sort on tiny arrays”,“Insertion sort on smallest arrays”

public class QuickSort {    public static <T extends Comparable<? super T>> void sort(T[] arr) {        sort(arr, 0, arr.length - 1, 16);    }    /**     * @param arr   待排序的數組     * @param left  左閉     * @param right 右閉     * @param k     當快排遞迴到子問題的規模 <= k 時,採用插入排序最佳化     * @param <T>   泛型,待排序可比較類型     */    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right, int k) {        // 規模小時採用插入排序        if (right - left <= k) {            insertionSort(arr, left, right);            return;        }        int p = partition(arr, left, right);        sort(arr, left, p - 1, k);        sort(arr, p + 1, right, k);    }    public static <T extends Comparable<? super T>> void insertionSort(T[] arr, int l, int r) {        for (int i = l + 1; i <= r; i++) {            T cur = arr[i];            int j = i - 1;            for (; j >= 0 && cur.compareTo(arr[j]) < 0; j--) {                arr[j + 1] = arr[j];            }            arr[j + 1] = cur;        }    }    private static <T extends Comparable<? super T>> int partition(T[] arr, int left, int right) {        //排序前,先讓基準值和隨機的一個數進行交換。這樣,基準值就有隨機性。        //就不至於在數組相對有序時,導致左右兩邊的遞迴規模不一致,產生最壞時間複雜度        swap(arr, left, (int) (Math.random() * (right - left + 1) + left));        T base = arr[left];        int j = left;        for (int i = left + 1; i <= right; i++) {            if (base.compareTo(arr[i]) > 0) {                j++;                swap(arr, j, i);            }        }        swap(arr, left, j);        return j;//返回一躺排序後,基準值的下角標    }    public static void swap(Object[] arr, int i, int j) {        if (i != j) {            Object temp = arr[i];            arr[i] = arr[j];            arr[j] = temp;        }    }    private static void printArr(Object[] arr) {        for (Object o : arr) {            System.out.print(o);            System.out.print("\t");        }        System.out.println();    }    public static void main(String args[]) {        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};        printArr(arr);//3   5   1   7   2   9   8   0   4   6        sort(arr);        printArr(arr);//0   1   2   3   4   5   6   7   8   9    }}

  

快速排序及最佳化(Java實現)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.