懵X排序算法:快速排序

原文地址:xeblog.cn/articles/17

快速排序基本思想

快速排序使用的是 分治思想,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

实现思路

  • 设置一个基准值 k ,一般取数组第一个元素,以此值分割数组;
  • 设置两个扫描员,分别为 iji 指向数组的最低位j 指向数组的最高位
  • 首先由 j 开始从数组最高位往数组最低位(j--)扫描比 k 小的值,扫描到后停止扫描,并将该值填入 i 所处的位置,然后再由 i 开始从数组最低位 往数组最高位(i++)扫描比 k 大的值,扫描到后停止扫描,并将该值填入 j 所处的位置,ji 依次扫描,直至 ji 的位置相互重合后,将 k 的值填入重合处,此时,数组左侧的值均小于 k,右侧值均大于 k,完成此次排序;
  • 分别对数组左右两边的值做如上操作后即可完成快速排序。

演示图

代码实现

    /**
     * 快速排序
     * @param array 待排序数组
     * @param begin 起点索引
     * @param end 终点索引
     */
    private static void fastSort(int[] array, int begin, int end) {
        // 递归终止条件,起点索引大于等于终点索引
        if (begin >= end) {
            return;
        }

        // 起点索引
        int i = begin;
        // 终点索引
        int j = end;
        // 基准值
        int k = array[begin];

        // 循环条件:起点索引小于终点索引
        while (i < j) {
            /*
            这个循环是要扫描小于基准值的值,扫描到后退出循环,
            循环条件:当前索引位的值大于等于基准值k(加等于号是防止相同数字交换而陷入死循环中),
            且起点索引小于终点索引(防止数组下标出界)
             */
            while (array[j] >= k && i < j) {
                // 终点索引位从右至左逐个递减
                j--;
            }

            if (i < j) {
                // 将小于基准值的数移至左侧
                array[i] = array[j];
            }

            /*
            这个循环是要扫描大于基准值的值,扫描到后退出循环,
            循环条件:当前索引位的值小于等于基准值k(加等于号是防止相同数字交换而陷入死循环中),
            且起点索引小于终点索引(防止数组下标出界)
             */
            while (array[i] <= k && i < j) {
                // 起点索引位从左至右逐个递增
                i++;
            }
            if (i < j) {
                // 将大于基准值的数移至右侧
                array[j] = array[i];
            }
        }
        if (array[j] != k) {
            // 基准值归位(数组的中间某个位置),归位后,基准值左侧都是小于基准值的数,右侧都是大于基准值的数
            array[j] = k;
        }
        // 递归将基准值左侧的数排序
        fastSort(array, begin, j - 1);
        // 递归将基准值右侧的数排序
        fastSort(array, j + 1, end);
    }
复制代码

测试排序

int[] array = {5, 6, 6, 4, 3, 5, 5};
System.out.println("排序前:" + Arrays.toString(array));
fastSort(array, 0, array.length - 1);
System.out.println("排序后:" + Arrays.toString(array));
复制代码

输出结果

排序前:[5, 6, 6, 4, 3, 5, 5]
排序后:[3, 4, 5, 5, 5, 6, 6]
复制代码

快速排序的时间复杂度

平均时间复杂度: O(nlogn)
最坏时间复杂度: O(n^2) ,这种情况发生在排序数组为正序逆序的时候。
稳定性: 不稳定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值