CoedTop006 手撕快排

排序数组
就是纯粹的一个快速排序的题,主要的注意点就是 选取元素的时候要随机 这样能够保证时间复杂度控制在O(nlogn).同时切记,快速排序的最坏情况下会降为复杂度O(n^2)
主要的就是理解快排的原理和手撕代码的流畅性吧.具体的一些小细节在代码中已经全部注释体现

public class Solution006 {
    public static void main(String[] args) {
        int[] nums = new int[]{3,2,1,5,6,4};
        QuickSort(nums);
        for(int i: nums){
            System.out.print(i+",");
        }
    }


    public static void QuickSort(int[] nums){
        if(nums==null || nums.length<2) return;
        QuickSort(nums,0,nums.length-1);
    }

    //对nums[left,right]区间进行排序操作
    public static void QuickSort(int[] nums,int left,int right){

        if(left<right){
            //随机选一个数和最后一个数做交换
            swap(nums,left+(int)(Math.random()*(right-left+1)),right);
            //划分值等于区域的左边界和右边界 这个数组返回的就是这两个边界的下标
            int[] p = partition(nums,left,right);
            //此时[left,less]是小于区  [less+1,more]是等于区 [more+1,right]是大于区
            //可以说明more就是这个随机数的位置
            QuickSort(nums,left,p[0]-1);//小于的区域进行快排
            QuickSort(nums,p[1]+1,right);//大于的区域进行快排
        }
    }

    //这个函数 用于将数进行左右区分 中间部分是等于划分值的元素区域 并且返回区分的左右边界
    public static int[] partition(int[] nums,int left,int right){
        int less = left-1;//小于区的右边界 注意是右边界
        int more = right;//大于区的左边界 注意是左边界
        //left表示当前数的位置  arr[right]表示的是我们设置的划分值
        while(left<more){
            if(nums[left]<nums[right]){//当前数<划分值
                //当前数和右边界+1位置做交换,然后右边界右移一位
                swap(nums,++less,left++);
            }else if(nums[left]>nums[right]){//当前数>划分值
                //当前数和左边界-1位置做交换,然后左边界左移一位
                swap(nums,--more,left);
            }else{
                left++;
            }
        }

        //此时num[right]是那个用于判断的数 但是它在比它的元素的右边 所以把它交换过去
        swap(nums,more,right);//这more是大于区的左边界
        //所以此时就是这么个情况[left,less]是小于区  [less+1,more]是等于区 [more+1,right]是大于区
        return new int[]{less+1,more};



    }

    public static void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值