快速排序过程图解,随机基数代码

随机在数组范围中找一个“基准值”,并将其与数组最右元素交换作为基准。

与此“基准值”进行比较就可以得到三个区域:小于,等于,大于。递归此过程就可以将数组排好序。

时间复杂度:由于随机选取一个数,那么每个数的概率就是 1/N ,拿到的这个数有可能构成最好情况,有可能构成不好不坏的情况,有可能构成最差情况。所以时间复杂度并不稳定。

那么通过前人的计算可以得到快速排序的时间复杂度:bigO(N*logN)

图解过程:

 

 

代码:

public static void quickSort(int[] arr){
        if (arr == null || arr.length < 2){
            return;
        }

        quickSort(arr,0,arr.length-1);
    }

    public static void quickSort(int[] arr,int left,int right){
        if (left < right){      //不越界

            //以数组最后一个数为“基准”,随机在数组取一个数,与最后一个数做交换。
            swap(arr,left + (int)(Math.random()*(right - left + 1)),right);

            //分层 <区 =区 >区
            int[] p = partition(arr,left,right);

            //递归,小于区递归,大于区递归
            quickSort(arr,left,p[0]-1);     //p[0]是分层后的数组 等于区的左边界 p[0]-1是 小于区的最后一个元素
            quickSort(arr,p[1]+1,right);     //p[1]是分层后的数组 等于区的右边界 p[1]+1是 大于区的第一个元素
        }
    }

    //荷兰国旗是以target目标值 作为划分
    //快速排序是以数组最右位置上的元素arr[R] 作为划分
    public static int[] partition(int[] arr,int left,int right){
        int less = left - 1;    //小于区的右边界
        int more = right;       //大于区的左边界
        int when = left;        //when代表当前值
        while (when < more){
            if (arr[when] < arr[right]){    //当前值 < 基准值
                swap(arr,++less,when++);
            }else if (arr[when] > arr[right]){
                swap(arr,--more,when);
            }else
                when++;
        }
        //此时已经分好区,把最后一个元素与>区第一个元素交换,得到左边:<基准值的区域,中间=基准值的区域,右边:>基准值的区域
        swap(arr,more,right);

        int[] res = {less + 1,more};
        return res;
    }

 

posted @ 2020-07-15 16:57  硬盘红了  阅读(681)  评论(0编辑  收藏  举报