《算法导论》第7章讲到了快速排序(quick sort),快速排序通常是用于排序的最佳的实用选择,因为其平均性能比较好。与合并算法相同,快速排序也是基于分治模式的,笔者再次选择整理扑克牌的情形来解释这一排序过程。
合并排序中,是将杂乱的牌堆分为两堆,依次再堆子堆牌分解,而在快速排序中,分出子牌堆加了些条件,我们将牌堆底部的牌作为对照牌,将牌堆中大于或者小于这张对照牌的牌分成左右两堆,然后利用同一规则继续对子牌堆分,最后得到的就是整理好的牌。
我们将这个排序过程用个函数去表示,首先是快速排序的分治递归部分,其伪代码如下:
if l < r
mid = PARTITION(A, l, r)
QuickSort(A, l, mid -1)
QuickSort(A, mid + 1, r)
其中PARTITION是最重要的部分,这个函数实现了数组的就地排序,其伪代码如下:
key = A[r]
i = l -1
for j : l to r - 1
if A[j] <= key
i++
A[j] <-> A[i]
i++
A[i] <-> A[r]
return i
给定一个实例,用C++实现快速排序的代码如下:
#include
void QuickSort(int A[], int l, int r);
int PARTITION(int A[], int l, int r);
int main(void)
{
int A[12] = {13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21};
QuickSort(A, 0, 11);
for (int i = 0; i < 12; i++)
std::cout << A[i] << " ";
}
void QuickSort(int A[], int l, int r)
{
if (l < r)
{
int mid = PARTITION(A, l, r);
QuickSort(A, l, mid - 1);
QuickSort(A, mid + 1, r);
}
}
int PARTITION(int A[], int l, int r)
{
int key = A[r];
int i = l - 1;
int temp = 0;
for (int j = l; j < r; j++)
{
if (A[j] <= key)
{
i++;
temp = A[j];
A[j] = A[i];
A[i] = temp;
}
}
i++;
A[r] = A[i];
A[i] = key;
return i;
}