快速排序算法 随机化分析

快速排序算法就是通过一趟排序将需要排序的数据分为某个数、小于这个数的所有数以及大于这个数的所有数,然后再递归的对小于这个数的部分以及大于这个数的部分进行排序。每一趟进行排序的过程也就是我们划分这些数据的过程。
快速排序的基本思想:首先对数组进行元素的划分,一般以第一个元素x为基准,将得到小于x的部分、x以及大于x的部分。再递归的对小于x的部分以及大于x的部分进行划分,直到所有元素都被划分。

//划分元素
public int partition(int[] array,int p,int q){
        int pivot=array[p];
        int i=p;
        int j=p+1;

        for(;j<=q;j++){
            if(array[j]<pivot){     
                swap(array,j,i+1);
                i++;
            }
        }       
        swap(array,i,p);
        return i;
    }
//递归对所有元素进行快速排序 
public void quick(int[] array,int p,int q){
        if(p<q){
            int r=partition(array,p,q);
            quick(array,p,r-1);
            quick(array,r+1,q);
        }       
    }

假设快速排序的时间复杂度为T(n),那么当数组本身已经完全有序的情况下,划分将得到两部分x以及除了x以外的其他元素(n-1)。由于划分一个元素就是遍历所有元素的过程,时间复杂度为O(n)。
T(n)=T(n-1)+O(n)

显然,当数组已经完全有序(顺序或者逆序),快速排序算法的时间复杂度为O(n2),和插入排序时间复杂度一样。

不过,如果数组划分后的结果是左右两边对称(n/2)呢?
T(n)=2T(n/2)+O(n)

显然,此时快速排序算法的时间复杂度为O(nlgn),时间复杂度又相当于归并排序和堆排序。

如果划分结果是n/10和9n/10呢?
显然时间复杂度的结果还是O(nlgn)

由此我们可以思考,如果快速排序是好坏情况随机进行呢?由上图的递归树思想可以知道,无论怎样划分,树的高度依然是lgn,而每层的时间都是O(n),在随机化快速排序的情况下,时间复杂度为O(nlgn)。
下面给出随机化快速排序算法的代码:

public int randomPartition(int[] array,int p,int q){
        int r = (int)(Math.random()*(q-p+1)+p);
        swap(array,p,r);
        return partition(array,p,q);
    }
    public void randomQuick(int[] array,int p,int q){
        if(p<q){
            int r = randomPartition(array,p,q);
            randomQuick(array,p,r-1);
            randomQuick(array,r+1,q);
        }   
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值