快速排序

      快速排序使用了分治思想。

      分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。其中,计算下标q也是划分过程的一部分。

      解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。

      合并:因为子数组都是原址排序的,所以不需要合并操作,数组A[p..r]已经有序。

      快速排序过程:

void quickSort(int A[],int p,int r)
{
    if(p<r)
    {
        int q=Partition(A,p,r);
        quickSort(A,p,q-1);
        quickSort(A,q+1,r);
    }
}

数组的划分

       算法的关键过程是Partition过程,它实现了对子数组A[p..r]的原址重排。

int Partition(int A[],int p,int r)
{
    int x=A[r];
    int i=p-1;
    for(int j=p;j<=r-1;j++)
    {
        if(A[j]<=x)
        {
            i++;
            int tmp=A[i];
            A[i]=A[j];
            A[j]=tmp;
        }
    }
    int tmp=A[i+1];
    A[i+1]=A[r];
    A[r]=tmp;
    return (i+1);
}

       Partition总是选择一个x=A[r]作为主元,并围绕它来划分子数组A[p..r]。随着程序的执行,数组被划分为四个区域。

      在循环体中,每一轮迭代开始时,对于任意数组下标i,有:

      1、若p<=k<=i,则A[k]<=x;

      2、若i+1<=k<=j-1,则A[k]>x;

      3、若k=r,则A[k]=x。

      

随机化版本

       前面始终采用A[r]作为主元,随机抽样是从子数组A[p..r]中随机选择一个元素作为主元。在子序列中随机选出一个元素,然后与A[r]互换,剩余部分与之前相同。

 

 

      

posted @ 2020-09-27 20:26  yanjan  阅读(110)  评论(0)    收藏  举报