快速排序Quick Sort(其三)-三路快排

快速排序Quick Sort(其三)-三路快排

存在的问题:
在普通快速排序和二路快排中都没有考虑等于arr[l]的问题,只是把数组分成小于arr[l]和大于arr[l]的两部分,而三路快速排序则是把数组分成小于arr[l],等于arr[l],大于arr[l]的三部分,这样分隔之后在递归的过程中,对于等于arr[l]的部分我们就不用了管了,下次递归时不必递归等于arr[l]的部分了,只需要递归的对小于arr[l]和大于arr[l]的部分进行同样的快速排序就好了。
解决方法:
Partition具体过程:
设置索引lt指向小于arr[l]的最后一个元素的位置,arr[l+1,…,lt]<arr[l],同样的设置gt指向大于arr[l]的第一个元素的位置,arr[gt,…,r]>arr[l],
现在在处理的元素为i,则arr[lt+1,…,i-1]==arr[l]。
在这里插入图片描述
当前待处理的元素arr[i] ==arr[l]时,i++就可以。
在这里插入图片描述
当前待处理的元素arr[i] <arr[l]时,将arr[i]这个元素与等于arr[l]的第一个元素(arr[lt+1])进行交换,同时lt++,i++。
在这里插入图片描述
当前待处理的元素arr[i] >arr[l]时,将arr[i]与大于arr[l]的部分的前一个元素(arr[gt-1])进行交换位置,同时gt–,指向大于arr[l]的第一个元素。此时i这个元素不用维护,i指向的元素没有被处理,是从gt-1这个位置换过来的。
在这里插入图片描述
遍历结束后,lt指向小于arr[l]的最后一个元素的位置,gt指向大于arr[l]的第一个元素的位置,i与gt重合。
在这里插入图片描述
最后将arr[l]与arr[lt]进行交换就可以了,此时lt指向等于arr[l]的第一个元素的位置。
在这里插入图片描述
在这里插入图片描述

 public void quickSort(E[] arr,int n){
        quickSort3(arr,0,n-1);
    }
     /**
     * 三路快速排序
     * 将arr[l,...,r]分为<v,==v,>v三部分
     * 之后递归对<v,>v两部分继续进行三路快速排序
     * @param arr
     * @param l
     * @param r
     */
    private void quickSort3(E[] arr, int l ,int r){
        if(l>=r){
            return ;
        }
        //三路快排不是简单地返回一个索引p,对(l- p-1)与(p+1,r)进行递归就好了
        //三路快排中等于v的是一个区间
        //partiton
        int index = (Math.abs(new Random().nextInt())%(r-l+1))+l;
        E t = arr[index];
        arr[index] = arr[l];
        arr[l]= t;

        E v = arr[l];
        int lt = l ;//arr[l+1,...,lt]<v
        int gt = r+1;//arr[gt,...,r]>v
        int i = l+1;//arr[lt+1,...,i)==v
        while (i<gt) {
            if(arr[i].compareTo(v)<0){
                E temp = arr[i];
                arr[i] = arr[lt+1];
                arr[lt+1] = temp;

                lt ++;
                i++;
            }else if(arr[i].compareTo(v)>0){
                E temp = arr[gt-1];
                arr[gt-1] = arr[i];
                arr[i] = temp;

                gt --;
            }else{
                //arr[i]  == v
                i++;
            }
        }

        E temp = arr[l];
        arr[l] = arr[lt];
        arr[lt] = temp;

        quickSort3(arr,l,lt-1);
        quickSort3(arr,gt,r);
    }

分治算法:分而治之,将原问题分割成同等结构的子问题,之后将子问题逐一解决后,原问题也就得到了解决。快速排序就是典型的分治算法,将原问题分割成同等结构的子问题,之后通过递归算法将子问题逐一解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值