快速排序详解(JAVA)

题目

对于数组使用快速排序算法进行排序
输入
[6,1,2,7,9,3,4,5,10,8]
输出
[1,2,3,4,5,6,7,8,9,10]

解析

假设我们现在对数据arr[6,1,2,7,9,3,4,5,10,8]这个10个数进行排序。
首先在这个序列中随便找一个数作为基准数。选取第一个数6作为基准数。在这个序列中,将所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列:[3,1,2,5,4,6,9,7,10,8]
在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。
具体步骤如下

  1. 使用指针i,j分别从左向右找大于6的数、从右向左找小于6的数。注意每次都是j先移动,找到满足条件的数后再移动i
    在这里插入图片描述

  2. 查找到符合条件的数arr[3],arr[7],交换二者
    在这里插入图片描述

  3. 继续移动i,j找到第二组满足条件的数,并交换二者
    在这里插入图片描述

  4. 继续移动i,j,先移动j,j=5,arr[j]=3,再移动i,i右移后与j重叠,终止移动。由于j先移动,此时停止有两种情况要么j移动到i要么j找到了小于基准数6的值,所以终止后将arr[j]与基准数交换
    在这里插入图片描述

  5. 至此第一轮探测结束,得到以6为基准数、左侧均小于6右侧均大于6的数组。以6为分界点,对6两边数组重复执行上述操作,直至排序出所有数据
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hkRYF3oO-1657007254427)(img_6.png)]

  6. 得到最终排序结果
    在这里插入图片描述

编码

	public static void main(String[] args) {
        int[] arr = {6,1,2,7,9,3,4,5,10,8};
        print("输入",arr);
        quickSort(arr,0,arr.length-1);
        print("输出",arr);
    }


    private static void quickSort(int[] arr, int left, int right) {
        // 起始大于终止时结束
        if(left>right){
            return;
        }
        int i = left;
        int j = right;
        int base = arr[left];
        while(i<j){
            // 右指针向左查找大于等于基准数的值
            while(i<j && arr[j] >= base){
                j--;
            }
            // 左指针向右查找小于等于基准数的值
            while(i<j && arr[i]<=base){
                i++;
            }
            // 如果左指针小于右指针,执行交换
            if(i<j){
                swap(arr,i,j,base);
            }
        }
        // 由于每次都是右指针先移动,那么上面循环终止条件要么j找到了小于等于基准数的值要么j=i,此时arr[j]一定小于等于基准数,执行交换
        if(left<i){
            swap(arr,left,i,base);
        }
        // 递归执行基准数左侧数组
        quickSort(arr,left,j-1);
        // 递归执行基准数右侧数组
        quickSort(arr,j+1,right);
    }

    private static void swap(int[] arr,int i,int j,int base){
        System.out.println("");
        print("执行交换[base="+base+",i="+i+",j="+j+"]");
        print("交换前",arr);
        int temp = arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
        print("交换后",arr);
    }

运行结果

执行交换[base=6,i=3,j=7]
交换前:[6,1,2,7,9,3,4,5,10,8]
交换后:[6,1,2,5,9,3,4,7,10,8]

执行交换[base=6,i=4,j=6]
交换前:[6,1,2,5,9,3,4,7,10,8]
交换后:[6,1,2,5,4,3,9,7,10,8]

执行交换[base=6,i=0,j=5]
交换前:[6,1,2,5,4,3,9,7,10,8]
交换后:[3,1,2,5,4,6,9,7,10,8]

执行交换[base=3,i=0,j=2]
交换前:[3,1,2,5,4,6,9,7,10,8]
交换后:[2,1,3,5,4,6,9,7,10,8]

执行交换[base=2,i=0,j=1]
交换前:[2,1,3,5,4,6,9,7,10,8]
交换后:[1,2,3,5,4,6,9,7,10,8]

执行交换[base=5,i=3,j=4]
交换前:[1,2,3,5,4,6,9,7,10,8]
交换后:[1,2,3,4,5,6,9,7,10,8]

执行交换[base=9,i=8,j=9]
交换前:[1,2,3,4,5,6,9,7,10,8]
交换后:[1,2,3,4,5,6,9,7,8,10]

执行交换[base=9,i=6,j=8]
交换前:[1,2,3,4,5,6,9,7,8,10]
交换后:[1,2,3,4,5,6,8,7,9,10]

执行交换[base=8,i=6,j=7]
交换前:[1,2,3,4,5,6,8,7,9,10]
交换后:[1,2,3,4,5,6,7,8,9,10]
输出:[1,2,3,4,5,6,7,8,9,10]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值