快速排序
快速排序通常是用于排序的最佳选择。虽然其在最坏的情况下运行时间为O(n^2),但是其平均性能相当好O(nlgn),且O(nlgn)中隐含的常数因子很小。另外,它还能够进行就地排序。
快速排序的描述
快速排序基于分治模式。 对数组A[p .. r]排序的分治过程:
- 分解: 数组A[p .. r]被划分成两个(可能空)子数组A[p .. q-1] 和 A[q+1 .. r], 使得A[p .. q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1 .. r]中的元素。下标q也在这个划分过程中进行计算;
- 解决: 通过递归调用快速排序,对子数组A[p .. q-1]和A[q+1 .. r]排序;
- 合并: 因为两个子数组是就地排序的,将它们合并不需要操作:整个数组A[p .. r]已经排序。
下图实现快速排序
数组划分:
快速排序中的PARTITION过程,对数组A[p .. r]进行就地重排
过程如下:
下图展示了PARTITION的操作过程:
这里,p指向数组的第一个元素,r指向数组的最后一个元素,i, j指定了数组A中大于元素A[r]的区间,i 指向起始位置的前一个位置,j 指向结束位置。当A[j]中的元素小于A[r]时,i后移一位(i = i+1),交换A[i]和A[j]. 直至j = r -1时,交换A[r]和A[i+1]的元素,返回 i+1.
完整的实现代码
/*
快速排序算法实现
*/
#include<iostream>
using namespace std;
//函数声明
int Partition(int A[], int p, int r);
void QuickSort(int A[], int p, int r)
{
int q;
if(p < r) //递归条件
{
q = Partition(A,p,r);
QuickSort(A, p, q-1);
QuickSort(A, q+1, r);
}
}
// 对数组进行就地重排
int Partition(int A[], int p, int r)
{
int i,j,x,temp;
x = A[r];
i = p-1; //i表示大于A[r]的子序列的下界的位置
for(j = p; j <= r-1; j++) //i表示大于A[r]的子序列的上界的位置
{
if(A[j] <= x)
{
i = i + 1;
// 交换A[i]和A[j]
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
temp = A[r];
A[r] = A[i+1];
A[i+1] = temp;
return i+1;
}
排序结果: