经典快排和随机快排

快速排序

经典快排根据荷兰国旗划分数组给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。,每次划分都拿最后一个数进行划分每次把小于等于num[R]的数放在数组的左半部分,大于num[R]的数放在数组的右半部分。记录等于num[R]的下标。

先讲述一下荷兰国旗的问题

 public static int[] flag(int[] arr,int num){
        //这个变量是小于num的下标
        int less=-1;
        int cur=0;
        //大于num的下标
        int more=arr.length;
        while (cur<more){
            if (arr[cur]==num){
                cur++;
            }else if (arr[cur]<num){
                swap(arr,++less,cur++);
            }else {
                swap(arr,--more,cur);
            }
        }
        return arr;
    }
 private static void swap(int[] arr, int i, int j) {
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }

经典快排

同样是拿最后一个数进行划分返回等于最后一个数的两个下标最后把大于区域第一个数和最后一个数进行划分重复子过程直到数组有序两种写法都可以区别只有一行代码。
分析

    public static void  partionionArr(int[] arr){
        partionionArrary(arr,0,arr.length-1);
        System.out.println();
    }

    private static void partionionArrary(int[] arr, int L, int R) {
        if (R>L){
        	
        	//   int[] p =partition(arr,L,R);
            int[] p = partitionQuick(arr, L, R); //经典快排
            partionionArrary(arr,L,p[0]-1);
            partionionArrary(arr,p[1]+1,R);
        }
    }
 public static int[] partitionQuick(int[] arr,int L,int R){
        int less=L-1;
        int more=R+1;
        int target=arr[R]; //每次拿最后一个数进行划分数组
        while (L<more){
            if (arr[L]==target){
                L++;
            }else if (arr[L]<target){
                swap(arr,++less,L++);
            }else {
                swap(arr,--more,L);
            }
        }
        //返回等于区域的位置下标
        return  new int[]{less+1,more-1};
    }
 public static int[] partition(int[] arr, int l, int r) {
        int less = l - 1;
        //最后一个数不参与遍历
        int more = r;
        while (l < more) {
            if (arr[l] < arr[r]) {
                swap(arr, ++less, l++);
            } else if (arr[l] > arr[r]) {
                swap(arr, --more, l);
            } else {
                l++;
            }
        }
        swap(arr, more, r);//把最后一个数和大于target的第一个数交换
        // //返回等于区域的位置下标
        return new int[] { less + 1, more };
    }
   private static void swap(int[] arr, int i, int j) {
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }

经典快排的问题

经典快排如果是在数组有序的情况下===(最坏的情况下)===时间复杂度是O(N^2)以为子过程的规模两个不相等。一般情况下时间复杂度为N*(LogN);

随机快排

随机快排是在其中随机选择一个数去划分数组把这个随机选的数和最后的位置交换在进行经典快排一样的操作。所有随机快排的时间复杂度为一个数学的长期期望值是一个固定的表达式N*(LogN);

 public static void  partionionArr(int[] arr){
        partionionArrary(arr,0,arr.length-1);
        System.out.println();
    }

    private static void partionionArrary(int[] arr, int L, int R) {
        if (R>L){
            swap(arr,L+(int) Math.random()*(R-L+1),R);
            int[] p = partition(arr, L, R);
            partionionArrary(arr,L,p[0]-1);
            partionionArrary(arr,p[1]+1,R);
        }
    }
    public static int[] partition(int[] arr, int l, int r) {
        int less = l - 1;
        int more = r;
        while (l < more) {
            if (arr[l] < arr[r]) {
                swap(arr, ++less, l++);
            } else if (arr[l] > arr[r]) {
                swap(arr, --more, l);
            } else {
                l++;
            }
        }
        swap(arr, more, r);
        return new int[] { less + 1, more }; 把最后一个数和大于target的第一个数交换
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值