排序算法——快速排序

来源:互联网 发布:资源分配软件 编辑:程序博客网 时间:2024/05/16 02:24

快速排序算法由于它的方便和高效在实践中一直得到广泛的应用,是排序算法中非常值得学习和掌握的一种。

思想

设定被排序的数组是A,快速排序算法的基本思想是用数组的首元素作为标准将A划分成前、后两个部分,比首元素小的元素构成数组的前部分,比首元素大的元素构成数组的后部分。这两个部分构成两个新的子问题,算法接着分别对这两部分递归地进行排序。算法的关键在于怎样划分数组A而将其归约成两个子问题。这里用到了分治的算法思想。

先从后向前扫描数组A,找到第一个不大于A[p]的元素A[j],然后再从前往后扫描数组A,找到第一个不小于A[p]的元素A[i],当i<j时,交换A[i]与A[j]的值。这时候A[j]后面的元素都大于A[p],A[i]前边的数都小于A[p]。然后继续进行扫描,直到i>j时,就岱庙了A[p]在排好序的数组中的正确位置q,然后将A[p]与A[q]的值交换,一次排序就完成了。然后将位置q左右的数组元素,分成两个部分,再次递归调用排序算法。

代码

void QuickSort(int numArr[], int p, int r){    int q;    if(p<r)    {        q = Partition(numArr,p,r);        QuickSort(numArr,p,q-1);        QuickSort(numArr,q+1,r);    }}int Partition(int numArr[],int p, int r){    int x = numArr[p];    int i = p;    int j = r;    while(1)    {        while(numArr[j]>x)            j--;        while(numArr[i]<x)            i++;        if(i<j)        {            int temp = numArr[i];            numArr[i] = numArr[j];            numArr[j] = temp;        }        else            return j;    }}


分析

下面对这个算法进行实践复杂度分析,首先说明划分过程的工作量是O(n),因为每个元素都需要和首元素进行1次比较。除了这个工作量外,就是两个子问题递归调用的工作量。在最坏的情况下,比如说逆序排列,那么子问题的规模每次都接近于当前的数组大小,那么它的递推方程就成为T(n) = T(n-1) + O(n),也就是说,它的时间复杂度为O(n^2)。

在一般的情况下,每一个子问题的规模都接近于n/2,那么在这样的情况下,递推方程就是T(n) = 2T(n/2) + O(n),根据主定理,可以得知它的时间复杂度为O(nlogn)。这是快速排序最好的情况。

0 0