1. 程式人生 > >排序演算法分析 --- 快速排序

排序演算法分析 --- 快速排序

一 演算法描述

假設有n個元素,現在要把這些元素按照從小到大的順序進行排序,那麼演算法步驟如下,

  1. 選擇中間位置的元素作為基準值(pivot value),其索引為( 0 + (n-1) ) / 2
  2. 從第0個元素開始從左往右找到比基準值大的元素,其索引為 i
  3. 從第n-1個元素開始從右往左找到比基準值小的元素,其索引為 j
  4. 交換這兩個元素
  5. 從索引 i 開始,繼續從左往右找到比基準值大的元素
  6. 從索引 j 開始,繼續從右往左找到比基準值小的元素
  7. 交換這2個元素
  8. 繼續查詢交換,直到 i > j,即發生了相遇
  9. 根據 ij 這2個索引,把元素分成兩部分,即[0, j]和[i, n-1],然後在這兩個部分裡繼續進行步驟1~8的操作

ps:基準值不一定要選擇中間位置的元素,可以選擇任意位置的元素

二 C程式碼

void quickSort(int arr[], int left, int right)
{
    int i = left, j = right; // 對i和j進行初始化
    int pivot = arr[(left+right)/2]; // 基準值選擇中間位置的元素
    int temp = 0;

    while (i <= j) // 跳出while迴圈說明i>j,而且i-j等於1
    {
        while (arr[i] < pivot && i <=
right) // 從左到右,找到比pivot大的元素 ++i; while (arr[j] > pivot && j >= left) // 從右到左,找到比pivot小的元素 --j; if (i <= j) //進行交換操作 { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; /* 一定要有這2步對i和j的更新,不然當i=j時while迴圈會無限執行下去 */
++i; --j; /******************************************************/ } } //對[left, j]做快速排序 if (left < j) quickSort(arr, left, j); //對[i, right]做快速排序 if (right > i) quickSort(arr, i, right); }

註釋:

  • while迴圈結束後,i 大於 j,且 j-i 等於1,這樣就把所有的元素分割成獨立的2塊,即[left, j]和[j, right],然後就可以進行遞迴操作繼續排序
  • 假設有10個元素,那麼該函式呼叫方式為quickSort(arr, 0, 9)

三 總結

快速排序使用了分而治之的思想,設計比較巧妙。理解的關鍵就是弄清從左到右和從右到左兩個方向的查詢和交換,以及這2個方向的相遇點。

如果有寫的不對的地方,希望能留言指正,謝謝閱讀。