第七章 快速排序
对于包含n个数的输入数组来说,快速排序是一种最坏情况复杂度为。虽然最坏情况时间复杂度很差,但是快速排序通常是实际排序应用中最好的选择,因为它的平均性能非常好,期望时间复杂度时,另外还他们进行原址排序(需要的内存空间小)。
该算法的思想是:对于数组A,选择一个主元r,并围绕它将数组划分为两个子数组,一个数组全部小于r,另一个数组全部大于r。递归的重复以上步骤,当划分子数组只包含一个元素时,排序完成。
过程如图所示:
上述过程主元r总是选择数组的最后一个。代码实现如下:
#include <iostream>
using namespace std;
int PARTITION(int *A, int p, int r)
{
int i = p-1;
for(int j = p; j < r; ++j)
{
if(A[j]<A[r])
{
i++;
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
int temp = A[i+1];
A[i+1] = A[r];
A[r] = temp;
return i+1;
}
void QUICK_SORT(int *A, int p, int r)
{
if(p < r)
{
int q = PARTITION(A, p, r);
QUICK_SORT(A, p, q-1);
QUICK_SORT(A,q+1, r);
}
}
int main()
{
int A[10] = {2, 8, 7, 1, 9, 5, 6, 4, 0, 3};
QUICK_SORT(A, 0, 9);
for(int i = 0; i < 10; ++i)
cout<<A[i]<<" ";
return 0;
}
由于上述过程我们每次都将最后一个数作为主元,对于输入数组该方法有可能得到较坏的结果。我们可以对上述算法设计一个随机过程,使之能够得到期望的算法复杂度。思路:在每次划分数组时,将A[r]与数组中随机元素A[i]进行交换。
修改上述int PARTITION(int *A, int p, int r)函数为:
int PARTITION(int *A, int p, int r)
{
int x = rand()%(r-p+1)+p;//交换随机一个元素
int temp = A[x];
A[x] = A[r];
A[r] = temp;
int i = p-1;
for(int j = p; j < r; ++j)
{
if(A[j]<A[r])
{
i++;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
temp = A[i+1];
A[i+1] = A[r];
A[r] = temp;
return i+1;
}