//分层方法+快速排序 (递归版本)

package quickSort;

/**
 * @author 真他喵的学不动咯
 * @create 2022-08-19--19:10
 */
public class quick {   //分层方法+快速排序

    //分层方法1
    public static void splitNum(int[] arr){
        int lessEqualR=-1;   //初始化为-1,防止越界
        int index=0;
        int mostR=arr.length-1;   //数组的最后一个数
        while (index<arr.length){
            if (arr[index]<=arr[mostR]){   //<=qu区
                swap(arr,lessEqualR+1,index);
                lessEqualR++;  //<=区右扩
                index++;       //指针也右扩
                //简化写法: swap(arr,++lessEqualR,index++)
            }else{
                index++;   //否则直接跳下一个
            }
        }
    }
    public static void swap(int[] arr,int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
    public static void main(String[] args){
        int[]arr ={7,1,2,56,45,2,45,1,7,6};
       // splitNum(arr);
        splitNum2(arr);
        for (int i=0;i<arr.length;i++){
            System.out.print(arr[i]+" ");  //小于等于6的在左,大于6的在右
        }
    }
    //分层方法2
    public static void splitNum2(int[] arr){
        int N=arr.length;
        int lessR=-1;   //小于区域的右边界
        int moreL=N-1;  //大于区域的左边界
        int index=0;
        while (index<moreL){  //如果向右的指针没有碰上大于区域的边界
            if (arr[index]<=arr[N-1]){   //就继续向右搜索
                //永远arr[N-1]做划分值
                swap(arr,++lessR,index++);   //向右扩
            }else if(arr[index]>arr[N-1]){
                swap(arr,--moreL,index);     //但是index不变
                moreL--;    //大于区域向左扩
            }else{   //等于划分值,直接index++
                index++;
            }
        }
        swap(arr,moreL,N-1);  //一直和划分值的位置做交换
    }

    //分层【用了递归】
    public static int[] partition(int[] arr, int L, int R){
        /*
        arr[L,...,R],arr[R做划分值
        L......R
        <  =   >
         */
        int lessR=L-1; //L-1为左边预备区域
        int moreL=R;   //R是右边第一区域
        int index=L;  //L是左边第一轮开始的地方,从L开始遍历
        while (index<moreL){
            if (arr[index]<arr[R]){
                swap(arr,++lessR,index++);
            }
            else if (arr[index]>arr[R]){
                swap(arr,--moreL,index);
            }else{
                index++;
            }
        }
        swap(arr,moreL,R);   //moreL和最后一个数进行了交换,所以下一句直接就是moreL,而不是moreL-1
        return new int[]{lessR+1,moreL};    //lessR+1 是等于区域的第一个,moreL是等于区域的最后一个
    }
    //快排
    public static void quickSort(int[] arr,int L,int R){
        if (arr==null||arr.length<1/2){
            return ;
        }
        process(arr,0,arr.length-1);
    }
    public static void process(int[] arr,int L,int R ){
        //边界条件
        if (L>=R){
            return;
        }
        //euqalE[0]  区域的第一个数
        //euqalE[1]  区域的最后一个数
        int[] euqalE=partition(arr,L,R);  //分层划分区域
        process(arr,L,euqalE[0]-1);   //  L   euqalE[0]-1 | euqalE[0]  euqalE[1] | euqalE[1]+1   R
        process(arr,euqalE[1]+1,R);   //    需要排序        ===  等于区域   ===           需要排序

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值