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

基本思想 :

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

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

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

非递归版本:

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

  1. 将 下标 0 和 arr.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);
        }
    }
相关推荐
kiracrimson2 天前
希尔排序:让插入排序不再怕逆序
数据结构·算法·排序算法
miller-tsunami11 天前
排序的相关知识点
数据结构·排序算法
wuyk55512 天前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
Zane199412 天前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
虚无的纽扣12 天前
【力扣刷题】第三天:有效三角形的个数、快乐数
算法·排序算法
无忧.芙桃12 天前
数据结构之排序算法(中):冒泡排序与快速排序,从相邻交换到工程级优化
c语言·c++·排序算法
Zane199414 天前
归并排序和堆排序都能保证O(nlogn),为什么谁也没法把稳定和原地两个优点占全
算法·排序算法
虚无的纽扣15 天前
【力扣刷题】第二天:无重复字符的最长字串、移动零问题
算法·leetcode·排序算法
多弗朗皮卡丘15 天前
数据结构9:排序算法
c语言·数据结构·排序算法
无忧.芙桃15 天前
数据结构之排序算法(上):从评价指标到插入、希尔、选择与堆排序
c语言·c++·排序算法