学习笔记-快速排序

快速排序

将一个一维数组从小到大排列。

思路

在这里插入图片描述
快速排序利用了递归的思想。需要三个参数,数组本身,数组起始索引也就是0,数组最右索引,也就是数组长度-1。
简单来说,快速排序的思想是这样的,先选择一个数作为基准数,把比它小的都移动到左边,把比它大的都移动到右边,然后针对左边这个子数组,再选择一个基准数,比它小的移到左边,比它大的移到右边,重复以上,直到子数组只剩1个数,这时候认为是有序的,返回到第一次,对右边子数组做同样的操作。
具体来说。用left记录数组最左边的索引,用right记录数组最右边的索引(同样也指子数组最左和最右,第一次的时候就是0和长度-1)。基准数每次都选最左边的数,也就是arr[left]。接着交错进行大小判断,因为基准数选的最左,所以要从最右开始判断,如果最右的数(arr[right])大于等于基准数(合适,加上等于的情况防止死循环,比如左右基准三数相等,就会左右反复交换死循环),就直接把索引right- -;如果最右的数小于基准数(不合适),就把他移到左边空位也就是arr[left](基准数保留,所以这个位置相当于空了;紧接着判断最左(arr[left]),如果最左的数小于等于基准数(合适),就直接把索引left++;如果最左的数大于基准数(不合适),就把他移到右边空位也就是arr[right](此时原来的arr[right]被移到到了左边所以这个位置就空出来了)。这样下去,当left==right时,两边就判断完了,此时把基准数放到中间(也就是left或者right,此时这里是空位)。接下来,进行左子数组,也就是开始递归调用自己,传入的数组起始索引还是0,但数组最右索引变成了right-1(因为此时基准数在right=left处,那左子数组最右就是right-1),然后开始右子数组,同理数组最右索引还是数组长度-1,数组起始索引就变成left+1。而循环退出的条件就是数组或子数组的长度为1,也就是传入的数组起始索引大于等于数组最右索引(俩索引相等时肯定只有一个数,大于是因为left+1,right-1这种操作可能会使left大于right,比如排完后基准数在最左,三个数都等于0,加减后,left就大于right了)

b站视频讲的很清楚,可以看这个

代码

 /**
     * 采用递归的思想
     * @param arr 数组和数组的左右子数组
     * @param L 数组的最左边和左右子数组的最左边
     * @param R 数组的最右边和左右子数组的最右边
     */
    private static void quickSort(int[] arr,int L,int R){
        //也就是子数组只剩一个值了,这时候就认为是有序的
        if(L>=R){
            return;
        }
        int left=L;
        int right=R;
        int pivot=arr[left];//基准数
        //因为right,left随时在变,所以每次操作都要判断大小
        while (left<right){
            while (left<right && arr[right]>=pivot){
                right--;
            }
            if(left<right && arr[right]<pivot){
                arr[left]=arr[right];
            }
            while (left<right && arr[left]<=pivot){
                left++;
            }
            if(left<right && arr[left]>pivot){
                arr[right]=arr[left];
            }
        }
        //左右排完后把基准数放中间
        if(left==right){
            arr[left]=pivot;
        }
        //排左边
        quickSort(arr,L,right-1);
        //排右边
        quickSort(arr,left+1,R);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值