輕鬆學習快速排序(二 )-- 快速排序最佳化

來源:互聯網
上載者:User

標籤:ati   源碼下載   median   imp   swap   href   media   ase   []   

在上一篇文章輕鬆學習快速排序(一 ) -- 基本的快速排序中介紹了快速排序的演算法,末尾提出了一個問題:例如這樣的一個數組:1 10 23 6 9 10,一般來說會選擇數組的第一個元素(也就是1)作為基準點,很顯然以數組的第一個元素1作為基準點,本來1就是這個數組中最小的一個數,那麼排序未達到預期的效果。如何來來選擇這個基準點呢?一般來說,所選擇的這個數最好是位於這個排序區間內所有數位中間(也就是中位元),這樣排序效果會最好。接下來,將會給出快速排序最佳化的兩種方式:三數取中法和小區間最佳化。

最佳化一:三數取中法

基本思想:選擇這組資料的第一個元素、中間的元素、最後一個元素,並在這三個數中取中間的元素作為基準點。比如有這樣一組元素:1 10 23 6 9 10 ,第一個元素、中間的元素。最後一個元素分別為:1,23,10,那麼這個中位元應該10。

選取中位元的實現代碼如下:

/** 擷取從left到right間的中位元的索引 */static int getMedianIndex(int[] arr, int left, int right) {    int mid = left + (right - left) >> 1;    if (arr[left] > arr[mid]) {        if (arr[left] < arr[right]) {            return left; // mid < left < right        } else {            if (arr[right] > arr[mid]) {                return right; // mid < right < left            }             return mid; // right < mid < left        }    } else {        if (arr[mid] < arr[right]) {            return mid; // left < mid < right        } else {            if (arr[left] > arr[right]) {                return left; // right < left < mid            }            return right; // left < right < mid        }    }}

 下面的代碼只不過是一些無聊的邏輯判斷,如果某個數M是中位元,那麼有 L <= M <= R,實際上上面的代碼就是按照這種特性來進行判斷的。

最佳化二:小區間最佳化

 當劃分的子區間的元素個數很小的時候(一般為十幾個,比如說13個),使用插入排序比快速排序更加的高效。因為如果區間的元素個數為13時,此時再繼續進行劃分的話,區間會比較小。下面的代碼是簡單的插入排序的實現:

/** 在數組中的left到right區間進行插入排序 */static void insertionSort(int[] arr, int left, int right) {    for (int m = left + 1; m <= right; m++) {        int pos = m;        while (pos != left && arr[pos - 1] > arr[pos]) {            int temp = arr[pos - 1];            arr[pos - 1] = arr[pos];            arr[pos] = temp;            pos--;        }    }}
最後的最佳化的結果

將上面兩種最佳化結合在一起,最終完成快速排序的最佳化,如下的代碼只給出了關鍵的一部分代碼,完成的代碼請點擊相關資源下面的本文例子代碼下載進行下載。

static void quickSort(int[] arr, int left, int right) {    if (left >= right) {        return;    }    int insertionThreshold = 13;    // 如果此區間只有13個元素,則直接進行插入排序    if (right - left + 1 <= insertionThreshold) {        insertionSort(arr, left, right);        return;    }    int first = left, last = right;    // 三數取中    int mid = getMedianIndex(arr, left, right);    swap(arr, mid, first);    int base = arr[first];    //... 其餘的代碼省略了}static void swap(int[] arr, int index1, int index2) {    int temp = arr[index1];    arr[index1] = arr[index2];    arr[index2] = temp;}
 相關資源
  • 本文例子源碼下載

輕鬆學習快速排序(二 )-- 快速排序最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.