C程序设计语言 - 快速排序算法

205 阅读2分钟

算法来自《C程序设计语言》章节4.10,书第87页。

算法思路

  • 将数组居中的元素作为pivot,并把pivot放在数组最左边;
  • index = 1开始,寻找比pivot更小的元素,并把找到的元素依次放在pivot的后面;
  • pivot与找到的最后一个比pivot小的元素对调,这样pivot前面的元素都小于pivotpivot后面的元素都大于pivot,且pivot所在的位置就是排序后的最终位置;
  • 使用recursion,对pivot之前和之后的子数组进行快速排序。

代码

void qsort(int v[], int left, int right) {
    int i, last;
    void swap(int v[], int i, int j);

    if (left >= right)
        return;
    /* 选择居中的元素作为pivot,并放在数组最左端 */
    swap(v, left, (left + right) / 2);
    last = left; 
    /* 从index = 1开始,寻找比pivot更小的元素,并以此排在pivot的后面 */
    for (i = left + 1; i <= right; i++)
        if (v[i] < v[left])
            swap(v, ++last, i); 
    
    /* 将pivot与找到的最后一个比pivot小的元素对调 */
    swap(v, left, last); 
    qsort(v, left, last - 1);
    qsort(v, last + 1, right);
} 

/* swap function */ 
void swap(int v[], int i, int j) {
    int temp; 

    temp = v[i]; 
    v[i] = v[j]; 
    v[j] = temp; 
}

实例

假设我们有如下数组:{15, 17, 19, 14, 3, 5, 7, 10}.
一共8个元素,代入到上面的函数,则:
left == 0;
right == 7;
last == 0;
pivot元素的index为(0 + 7)/2 = 3,即14。将15与14对调,得数组:
{14, 17, 19, 15, 3, 5, 7, 10}
接下来寻找比pivot元素值小的元素:
3 < 14,将3与17对调,得{14, 3, 19, 15, 17, 5, 7, 10},last == 1
5 < 14,将5与19对调,得{14, 3, 5, 15, 17, 19, 7, 10},last == 2
7 < 14,将7与15对调,得{14, 3, 5, 7, 17, 19, 15, 10},last == 3
10 < 14,将10与17对调,得{14, 3, 5, 7, 10, 19, 15, 17},last == 4
将14与10对调,得{10, 3, 5, 7, 14, 19, 15, 17},这样14之前的元素都小于14,14之后的元素都大于14。
接下来对{10, 3, 5, 7}和{19, 15, 17}分别进行快速排序。