快速排序(递归和非递归)

基本思想 :

选择最后一个数组元素作为 基准值

排序将基准值的左区间 都放 小于基准值的元素 ;基准值右区间 都放 大于基准值的元素

将以上操作应用在 以基准值为分界线的 左区间 和 右区间

非递归版本:

栈里存放 要处理的区间范围的下标

  1. 将 下标 0arr.length - 1 入栈

  2. 循环出栈:出栈2个栈顶元素 就是 要处理的区间下标

  3. 调用 partition 分隔区间 得到 2 个子区间

    a) 得到的子区间只有 1 个 或 0 个元素 不入栈(不处理)

    b) 有更多的内容再入栈 子区间

  4. 直到栈为空,排序完成

代码实现

java 复制代码
 public static void quickSort(int[] arr) {
        //区间采用左闭右闭
        quickSortHelper(arr,0,arr.length-1);
    }

    private static void swap(int[] arr, int index1, int index2) {
        int temp = arr[index1];
        arr[index1] = arr[index2];
        arr[index2] = temp;
    }

    private static int partition(int[] arr,int left,int right){
        int l = left;
        int r = right;
        //设置基准值 为当前区间的右边(下标为 right)的数组元素
        int value = arr[right];
        while (l < r) {
            //左边找比基准值大的数字
            while(l < r && arr[l] < value) {
                l++;
            }
            //右边找小于基准值的数字 不包括基准值 所以是 >=
            while(l < r && arr[r] >= value) {
                r--;
            }
            swap(arr, l, r);
        }
        //l r相遇时的下标的数组元素 和 基准值 交换
        swap(arr, l, right);
        //返回基准值的下标
        return l;
    }

    private static void quickSortHelper(int[] arr,int left,int right) {
        //left == right 是只有一个元素 
        //left > right 是没有元素
        //如果得到的区间只有 1 个 或 0 个元素 不处理
        if(left >= right){
            return;
        }
        int index = partition(arr,left,right);
        //[left index - 1]
        quickSortHelper(arr,left,index-1);
        //[index+1 right]
        quickSortHelper(arr,index+1,right);
    }

       //快速排序的非递归版本
    public static void qickSortByLoop(int[] arr){
        Stack<Integer> stack = new Stack<>();
        //栈里存放的是 排序范围的下标
        stack.push(0);
        stack.push(arr.length-1);
        while(!stack.isEmpty()){
            //取出要处理的区间
            int right = stack.pop();
            int left = stack.pop();
            //如果得到的区间只有 1 个 或 0 个元素 不处理
            if(left >= right){
                continue;
            }
            int index = partition(arr,left,right);
            //内容更多再处理
            stack.push(index + 1);
            stack.push(right);
            stack.push(left);
            stack.push(index - 1);
        }
    }
相关推荐
王老师青少年编程21 小时前
信奥赛csp初赛高频考点【排序算法】(详细解析)
c++·排序算法·csp-j·csp·高频考点·初赛·信奥赛
LuminousCPP2 天前
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
c语言·数据结构·笔记·算法·排序算法
LuminousCPP3 天前
数据结构-排序(一):基础排序算法横向对比|冒泡、插入、希尔、堆与双向选择,详解二分 / Knuth 增量
c语言·数据结构·笔记·算法·排序算法
Cccp.1234 天前
【leetcode】(四)排序算法汇总和链表
leetcode·链表·排序算法
LayZhangStrive4 天前
数据结构与算法 - 堆排序
java·数据结构·算法·排序算法·堆排序·大根堆
wuyk5554 天前
13.堆排序:基于完全二叉树的高效排序算法一、什么是堆排序?
开发语言·算法·排序算法
青山木5 天前
Hot 100 --- 数组中的第K个最大元素
java·数据结构·算法·排序算法
wuyk5555 天前
12.归并排序:分治思想的稳定排序算法
开发语言·数据结构·算法·排序算法
明月_清风8 天前
十大经典排序算法 Go 实现全解:从入门到面试通关
后端·算法·排序算法
凉茶钱8 天前
【数据结构】计数排序
数据结构·算法·排序算法