图解:快速排序之单边循环法

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
容器镜像服务 ACR,镜像仓库100个 不限时长
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 单边循环法是快速排序的算法之一,之前的双边循环法从数列的两边交替遍历元素,虽然更加直观,不过代码实现起来相对复杂。而单边循环法就要简单多了,只需要从数组的一边对元素进行遍历和交换即可。

一、单边循环法概述

单边循环法是快速排序的算法之一,之前的双边循环法从数列的两边交替遍历元素,虽然更加直观,不过代码实现起来相对复杂。而单边循环法就要简单多了,只需要从数组的一边对元素进行遍历和交换即可。

二、逻辑推演

单边循环法的详细过程,假设数列为:[4,7,3,5,6,2,8,1]

image-20211104183334590

开始和双边循环法相似,首先选定基准元素。同时,设置一个mark指针记录数列的起始位置,该指针代表小于基准元素的区域边界。

image-20211104183450971

接着,从基准元素的下一个位置开始遍历数组。

如果遍历到元素大于基准元素,就继续往后遍历。

如果遍历到元素小于基准元素,则要做两件事:1.把mark指针右移1位,因为小于基准元素的区域边界增大了1;2.让最新遍历到的元素和mark指针所在位置的元素交换位置,因为最新遍历的元素归属于小于基准元素的区域。

先遍历元素到7,因为7>4所以继续向后遍历。

image-20211104183617085

然后遍历到元素3,3<4,所以mark指针右移1位。

image-20211104183726117

元素3和mark指针所在位置的元素交换,因为元素3属于小于基准元素的区域。

image-20211104183907169

如果按照这个思路继续遍历的话,图就如下所示了。

image-20211104184228947

省略中间的过程...最后把基准元素交换到mark指针所在位置,这一轮宣告结束,得到这样一个排列

image-20211104184445550

此时这一轮排序宣告结束,继续下一轮排序。

这个方法只需要单边循环,确实简单了许多,下面我们用代码来实现

三、代码实现

    public static void main(String[] args) {
   
   
        int[] arr = new int[]{
   
   4,3,7,5,6,2,8,1};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void quickSort(int[] arr,int startIndex,int endIndex){
   
   
        //递归结束条件:startIndex大于等于endIndex
        if(startIndex>=endIndex){
   
   
            return;
        }
        //获取基准元素
        int pivotIndex = partition(arr,startIndex,endIndex);
        //根据基准元素分成两部分进行排序操作
        quickSort(arr,startIndex,pivotIndex-1);
        quickSort(arr,pivotIndex+1,endIndex);
    }
    //单边循环分治
    private static int partition(int[] arr, int startIndex, int endIndex) {
   
   
        //获取第一个位置,成为基准元素
        int pivot = arr[startIndex];
        int mark = startIndex;
        for (int i = startIndex+1; i <=endIndex ; i++) {
   
   
            if(arr[i]<pivot){
   
   
                mark++;
                int p = arr[mark];
                arr[mark]=arr[i];
                arr[i]=p;
            }
        }
        arr[startIndex] = arr[mark];
        arr[mark]=pivot;
        return mark;
    }

总结

以递归为基础的单边循环法成功实现排序,其实除了递归实现以外,我们还可以使用非递归的实现方式完成快速排序,非递归的方式在下一篇文章。

目录
相关文章
|
5月前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
7月前
|
人工智能 算法 C语言
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
46 0
|
搜索推荐
图解:快速排序算法之双边循环法
之前我们学习了冒泡排序,有没有比冒泡排序更快的排序算法呢?当然有,例如快速排序,归并排序,堆排序。接下来即将介绍的快速排序就是由冒泡排序演变而来的。
226 0
图解:快速排序算法之双边循环法
|
搜索推荐
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(上)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(上)
195 0
|
算法 搜索推荐
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
213 0
|
存储 人工智能 分布式计算
动态规划从理论到实践-深入理解贪心/分治/回溯/动态规划的算法思想
动态规划从理论到实践-深入理解贪心/分治/回溯/动态规划的算法思想
257 0
|
机器学习/深度学习 存储 分布式计算
算法思想--分治算法
分治算法是一种常见的算法思想,其基本思想是将一个大问题分解成若干个小问题,然后通过递归的方式解决每个小问题,最后将所有小问题的解合并起来得到大问题的解。分治算法通常包含三个步骤:分解、解决和合并....
128 0
算法思想--分治算法
|
存储 搜索推荐 算法
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(下)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(下)
138 0
|
搜索推荐 算法 索引
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(中)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(中)
86 0
|
存储 搜索推荐 索引
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】(二)
快排图文详解:快速排序算法的实现 - 【双边循环法与单边循环法 & 递归与非递归(栈的方式)的实现】
206 0