快速排序

概述

执行流程

  1. 从序列中选择一个轴点元素(pivot)。假设每次选择第一个位置的元素为轴点元素;
  2. 利用pivot将序列分割成2个子序列 。 将小于pivot的元素放到pivot前面(左侧);将大于pivot的元素放到pivot后面(右侧);等于pivot的元素放到哪都可以;
  3. 对子序列进行1、2操作。直到不能再分割(子序列中只剩下一个元素);

案列图
在这里插入图片描述
快速排序的大致思想我们了解了,关键是我们怎么构建轴点呢?

轴点构造

  1. 一般选取数组的第一个元素作为轴点元素(pivot)
  2. 将轴点元素(pivot)备份一份,后面会用
  3. begin表示坐标,初始值是轴点坐标;end表示坐标,初始值是最后元素下标;
  4. 从右向左开始检索。如果end坐标的元素大于轴点元素,则不用动,end–;检索下一个end,如果end坐标元素小于轴点元素,则将end元素赋值给begin坐标(因为之前pivot已经备份了,所以不会造成数据丢失),然后让begin++,开始从左向右检索
  5. 从左向右开始检索。如果begin坐标的元素小于轴点元素,则不用动,begin++;检索下一个begin,如果begin坐标元素大于轴点元素,则将begin元素赋值给end坐标,然后让end–,开始从右向左检索
  6. 重复 4、5 操作直到begin==end
  7. 最后找到的轴点下标就是begin
    在这里插入图片描述

代码实现

package 排序算法;

public class 快速排序 {
    public static void main(String[] args) {
        int[] arr = {0,9,8,6,5,7,3,1,2,4,0,10,11,12,13,15};
        System.out.println("排序前:");
        for(int i: arr){
            System.out.print(i+" ");
        }
        sort(arr, 0, arr.length-1);
        System.out.println();
        System.out.println("排序后:");
        for(int i: arr){
            System.out.print(i+" ");
        }
    }


    /**
     * 快速排序算法 (sort + pivotIndex)
     * @param arr
     * @param begin
     * @param end
     */
    // 核心逻辑
    public static void sort(int[] arr, int begin, int end) {
        if (end - begin <= 0) return; // 终止条件是,序列只剩下一个元素
        // 确定轴点的位置
        int mid = pivotIndex(arr, begin, end);
        // 对子序列进行排序
        sort(arr, begin, mid-1);
        sort(arr, mid+1, end);

    }
    // 找到中心轴
    public static int pivotIndex(int[] arr, int begin, int end) {
        // 备份begin下标的元素,作为中心轴元素
        int pivot = arr[begin];
        while (begin<end) { // 循环条件是begin<end,如果begin=end说明找到了中心轴,退出循环
            /**
             * 从右向左开始检索
             */
            while (begin<end && arr[end]>pivot) { // 如果begin<end且end下标的值大于pivot,则不发生交换,用下个end与pivot比较
                end--;
            }
            if (begin<end) { // 进入这个代码块说明 arr[end]<=pivot
                arr[begin] = arr[end];  // 让end元素赋值给begin元素(初始时,已经备份了arr[begin],因此不会造成数据丢失)
                begin++; // 勿忘让begin++,开始从左向右检索
            }
            /**
             * 从左向右开始检索,这里逻辑跟上面类似,我就不做注释了
             */
            while (begin<end && arr[begin]<pivot) {
                begin++;
            }
            if (begin<end) {
                arr[end] = arr[begin];
                end--;
            }
            /**
             *  如果begin=end说明找到了中心轴,退出循环
             */
            if (begin==end) {
                arr[begin] = pivot;
            }
        }
        return begin; // 返回中心轴坐标
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coderzpw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值