排序演算法分析 --- 快速排序
阿新 • • 發佈:2018-12-16
一 演算法描述
假設有n個元素,現在要把這些元素按照從小到大的順序進行排序,那麼演算法步驟如下,
- 選擇中間位置的元素作為基準值(pivot value),其索引為( 0 + (n-1) ) / 2
- 從第0個元素開始從左往右找到比基準值大的元素,其索引為 i
- 從第n-1個元素開始從右往左找到比基準值小的元素,其索引為 j
- 交換這兩個元素
- 從索引 i 開始,繼續從左往右找到比基準值大的元素
- 從索引 j 開始,繼續從右往左找到比基準值小的元素
- 交換這2個元素
- 繼續查詢交換,直到 i > j,即發生了相遇
- 根據 i、j 這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個方向的相遇點。
如果有寫的不對的地方,希望能留言指正,謝謝閱讀。