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

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 单边循环法是快速排序的算法之一,之前的双边循环法从数列的两边交替遍历元素,虽然更加直观,不过代码实现起来相对复杂。而单边循环法就要简单多了,只需要从数组的一边对元素进行遍历和交换即可。

一、单边循环法概述

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

二、逻辑推演

单边循环法的详细过程,假设数列为:[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月前
|
人工智能 算法 C语言
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
数据结构与算法——简单排序-冒泡排序、插入排序,时间复杂度下界(图示、代码、时间复杂度、定理)
36 0
|
搜索推荐
图解:快速排序算法之双边循环法
之前我们学习了冒泡排序,有没有比冒泡排序更快的排序算法呢?当然有,例如快速排序,归并排序,堆排序。接下来即将介绍的快速排序就是由冒泡排序演变而来的。
181 0
图解:快速排序算法之双边循环法
|
搜索推荐
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(上)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(上)
174 0
|
算法 搜索推荐
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
186 0
|
11月前
|
搜索推荐 算法 C语言
手撕排序算法3:优化版冒泡排序和快速排序的三种方法(包括三数取中,小区间优化,递归版本)(上)
手撕排序算法3:优化版冒泡排序和快速排序的三种方法(包括三数取中,小区间优化,递归版本)(上)
手撕排序算法3:优化版冒泡排序和快速排序的三种方法(包括三数取中,小区间优化,递归版本)(上)
|
6月前
|
机器学习/深度学习 算法 搜索推荐
【算法训练-排序算法 一】【手撕排序】快速排序、堆排序、归并排序
【算法训练-排序算法 一】【手撕排序】快速排序、堆排序、归并排序
85 0
|
11月前
|
搜索推荐 算法
手撕排序算法3:优化版冒泡排序和快速排序的三种方法(包括三数取中,小区间优化,递归版本)(下)
手撕排序算法3:优化版冒泡排序和快速排序的三种方法(包括三数取中,小区间优化,递归版本)(下)
|
机器学习/深度学习 存储 算法
【数据结构与算法篇】手撕八大排序算法之快排的非递归实现及递归版本优化(三路划分)
【数据结构与算法篇】手撕八大排序算法之快排的非递归实现及递归版本优化(三路划分)
209 0
|
搜索推荐 算法 索引
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(中)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(中)
82 0
|
存储 搜索推荐 算法
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(下)
“掌握更多的快速排序技巧:三路划分、双路快排和非递归的深入理解”(下)
130 0
下一篇
无影云桌面