算法来自《C程序设计语言》章节4.10,书第87页。
算法思路
- 将数组居中的元素作为
pivot
,并把pivot
放在数组最左边; - 从
index = 1
开始,寻找比pivot
更小的元素,并把找到的元素依次放在pivot
的后面; - 将
pivot
与找到的最后一个比pivot
小的元素对调,这样pivot
前面的元素都小于pivot
,pivot
后面的元素都大于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}分别进行快速排序。