快速排序

本文详细介绍了快速排序算法,包括其特点、时间复杂度和空间复杂度。针对快速排序的效率问题,提出了优化策略,如基准值的选择和在小规模数据中使用插入排序。同时,提供了递归和非递归两种实现方式的代码示例,帮助读者深入理解快速排序的工作原理。
摘要由CSDN通过智能技术生成

快速排序

-快速排序的特点

  1. 不稳定
  2. 时间复杂度 ( O(N * log(N)) ~ O(N^2) 最好 ~ 最坏 )
  3. 空间复杂度 ( O( log(N)) ~ O(N) 最好 ~ 最坏 )

-快速排序的优化方法

  1. 基准值选取数组第一个元素, 中间元素, 末尾元素的中间数
  2. 当待排序区间较小的时候, 直接使用插入排序
  3. 当递归深度达到一定深度, 但待排序区间还是很大时, 直接使用堆排序

-快速排序的原理

此处以升序为例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

-快速排序的代码

	public static void quickSort(int[] arr){
        quickSort2(arr, 0, arr.length-1);
    }

    private static void quickSort2(int[] arr, int left, int right) {
        if(left >= right){
            return ;
        }
        int index = partition(arr, left, right);
        quickSort2(arr, left, index-1);
        quickSort2(arr, index+1, right);
    }

    private static int partition(int[] arr, int left, int right) {
        //选取基准值
        int val = arr[right];
        int l = left;
        int r = right;
        while(l < r){
            //如果基准值选的是末尾元素 那么就要先让 left 从左向右走
            //如果基准值选的是最左侧元素 那么就要先让 right 从右向左走
            while(l < r && arr[l] <= val){
                //从左往右走, 遇到比基准值小的就跳过
                //出循环时, l 指向的就是比基准值大的第一个元素
                l++;
            }
            while(l < r && arr[r] >= val){
                //从右往左走, 遇到比基准值大的就跳过
                //出循环时, r 指向的就是比基准值小的第一个元素
                r--;
            }
            //交换 l 和 r
            int tem = arr[l];
            arr[l] = arr[r];
            arr[r] = tem;
        }
        //此时 l 和 r 重合了, 就交换重合位置和基准值
        int tem = arr[right];
        arr[right] = arr[l];
        arr[l] = tem;
        //最后返回重合位置的 index
        return r;
    }

-快速排序的非递归写法

	public static void quickSortNoR(int[] arr){
        //非递归写法和先序遍历的非递归写法差不多
        //先创建一个栈
        Stack<Integer> stack = new Stack<>();
        //再把左右区间都入栈 如果先把 left 入栈就要后出 left
        stack.push(0);
        stack.push(arr.length-1);
        while(!stack.isEmpty()){
            int right = stack.pop();
            int left = stack.pop();
            if (left >= right) {
                continue;
            }
            int index = partition(arr, left, right);
            //右侧区间为 [index+1, right]
            stack.push(index+1);
            stack.push(right);
            //左侧区间为 [left, index-1]
            stack.push(left);
            stack.push(index-1);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值