快速排序主要过程如下:
分解:数组A[p..r]被划分为两个(可能为空的)子数列A[p..q-1]和A[q+1..r],使得A[p..q-1]中元素都小于等于A[q],A[q+1..r]中元素都大于A[q]。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。
合并:因为子数组都是原址排序,所以不需要合并,数组A[p..r]已经有序。
非随机化版本的快速排序实现如下:
int partition(int *source, int head, int tail) {
int x = source[tail];
int i = head - 1, j = head;
for (j = head; j < tail; j++) {
if (source[j] <= x) {
i++;
swap(source + j, source + i);
}
}
swap(source + tail, source + i + 1);
return i + 1;
}
void quick_sort(int *source, int head, int tail) {
if (head >= tail)
return;
int mid = partition(source, head, tail);
quick_sort(source, head, mid - 1);
quick_sort(source, mid + 1, tail);
}
注意,对于一个几乎有序的排列,插入排序的性能往往要优于快速排序。由逆序对内容可知,插入排序的运行时间为
随机化版本实现如下:
int randomized_partition(int *source, int head, int tail) {
swap(source + rand() % (tail - head + 1) + head, source + tail);
int x = source[tail];
int i = head - 1, j = head;
for (j = head; j < tail; j++) {
if (source[j] <= x) {
i++;
swap(source + j, source + i);
}
}
swap(source + tail, source + i + 1);
return i + 1;
}
void randomized_quick_sort(int *source, int head, int tail) {
if (head >= tail)
return;
int mid = randomized_partition(source, head, tail);
randomized_quick_sort(source, head, mid - 1);
randomized_quick_sort(source, mid + 1, tail);
}
在划分前,随机选取一个元素于尾部将作为主元的元素交换,再进行划分。