快速排序思想与模板分析【排序算法篇】

思想
假 设 数 组 的 某 个 数 作 为 基 准 , 我 们 将 比 基 准 小 的 数 放 置 在 基 准 的 左 侧 , 比 基 准 大 的 数 放 在 基 准 的 右 侧 。 假设数组的某个数作为基准,我们将比基准小的数放置在基准的左侧,比基准大的数放在基准的右侧。
我 们 通 过 分 治 , 将 基 准 的 左 侧 部 分 和 右 侧 部 分 分 为 两 个 小 数 组 进 行 如 上 操 作 , 直 到 数 组 长 度 为 1 。 我们通过分治,将基准的左侧部分和右侧部分分为两个小数组进行如上操作,直到数组长度为1。 1 这 样 就 可 以 将 所 有 的 数 都 进 行 如 上 的 操 作 , 我 们 便 可 以 得 到 一 个 有 序 数 组 。 这样就可以将所有的数都进行如上的操作,我们便可以得到一个有序数组。 便

图解

取自网络
在这里插入图片描述

代码模板

    public void get() {
        int[] arr = new int[]{3, 4, 5, 2, 1, 7, -1, 9, 0};
        quickSort(arr, 0, arr.length - 1);
        for (int i : arr) {
            System.out.println(i);
        }
    }

    

public void quickSort(int[] arr, int left, int right) {
        //结束条件:当左右指针指向同一位置时,意味着区间长度为1,无需找基准,挖坑填数,直接返回即可
        if (left >= right) return;
        //获取当前区间的第一个值的索引,和最后一个值的索引
        int i = left, j = right;
        //首先获取当前区间的第一个值(具体获取哪个值做基准,将影响快排效率),此时arr[i]成为了坑
        int tmp = arr[i];
        //左右挖坑填数,循环接替,直到所有比基准小的数放置基准的左侧,比它大的数放置在它的右侧
        //当左右指针相遇意味着,我们已经将所有的数都与基准比较过了,结束循环
        while (i < j) {
            //因为现在arr[i]是坑,我们先从右指针指向的值开始,
            //若比基准大,右指针向左移动
            while (i < j && tmp < arr[j]) {
                j--;
            }
            //否则把arr[j]填入arr[i]中,此时arr[j]成为了坑
            if (i < j) {
                arr[i] = arr[j];
                i++;
            }
            //因为现在arr[j]是坑,我们则从左指针指向的值开始,
            //若比基准小,左指针向右移动
            while (i < j && tmp > arr[i]) {
                i++;
            }
            //否则把arr[i]填入arr[j]中,此时arr[i]成为了坑
            if (i < j) {
                arr[j] = arr[i];
                j--;
            }
        }
        //不要忘了,把基准填入最后的坑中
        arr[i] = tmp;
        //分治
        //通过以上的操作,基准的位置不会变了
        //但基准的左侧和右侧的数还处于无序的状态
        //我们通过分治递归的方法,遍历所有的数,将所有的数都找到其对应的位置
        quickSort(arr, left, i - 1);
        quickSort(arr, i + 1, right);
    }
  • 需注意的一点是:我们必须时刻监控左右指针的位置,放置出现i>j时,却依旧进行挖坑填数操作。

快 速 排 序 : 时 间 复 杂 度 O ( n l o g n ) 、 空 间 复 杂 度 O ( l o g n ) 快速排序:时间复杂度O(nlogn)、空间复杂度O(logn) O(nlogn)O(logn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值