(九)Java算法:快速排序(详细图解)

news2025/2/28 20:09:41

目录

    • 一、前言
      • 1.1、概念
      • 1.2、算法过程
    • 二、maven依赖
    • 三、流程解析
      • 3.1、全部数据分区
      • 3.2、左边数据分区
      • 3.3、右边数据分区
    • 四、编码实现
    • 结语

一、前言

1.1、概念

   快速排序:用数组的第一个数作为基准数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

1.2、算法过程

  1. 数组为arr,设置两个变量leftright,排序开始的时候:left=0,right=arr.length-1
  2. 以第一个数组元素作为关键数据,赋值给key,即key=A[left]
  3. right开始向前搜索,即从后向前搜索(right–),找到第一个小于key的值 arr[right],将 arr[right]arr[left] 的值交换,如果不满足(即3中arr[right]不小于key),则right=right-1
  4. left开始向后搜索,即从前向后搜索(left++),找到第一个大于keyarr[left],将arr[left]arr[right] 的值交换,如果不满足(即4中arr[left]不大于key),则left=left+1
  5. 重复第3、4步,直到left==right (3,4步中,找到符合条件的值,进行交换的时候leftright指针位置不变。另外,left==right 时循环结束)

二、maven依赖

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.14</version>
    </dependency>
</dependencies>

三、流程解析

  假设我们要排序的数据是:19, 28, 8, 23, 10, 21, 9

3.1、全部数据分区

  先看看全部数据分区是怎么做的,后续递归过程和这个是一样的。

在这里插入图片描述

  我们找的基准值是要分区的数组的首个元素:arr[left]=arr[0]=19,你也可以选其他的位置,比如中间,或者尾部,因为我们选的是首部,那么开始遍历的位置就是从右边开始,这个很重要哦。经过我们的分区之后,19左边的元素都比19要小,19右边的数据都比19要大

3.2、左边数据分区

  左边部分分区过程如下:

在这里插入图片描述

  左边分区的数据都是全部数据分区的基准值19左边的元素,不涉及到19右边的元素,找的基准值是分区的数组的首个元素:9。经过我们的分区之后,9左边的元素都比9要小,9右边的数据都比9要大

3.3、右边数据分区

  右边部分分区过程如下:

在这里插入图片描述
  右边分区的数据都是全部数据分区后的基准值19右边的元素,不涉及到19左边的元素,同样找的基准值是要分区的数组的首个元素:23。经过我们的分区之后,23左边的元素都比23要小,23右边的数据都比23要大。实际以为我们目前的数据来说,数组已经是有序的了。

四、编码实现

  上面我们演示了一个基本的流程,如果数据更多,就继续按照左边和右边继续分区,实际上就是一个递归。我们看看具体的实现就懂了。

    public static void quickSort(int[] arr, int left, int right) {
        if (left < right) {
            log.info("开始排从【arr[{}]】到【arr[{}]】数据", left, right);
            int pivot = partition(arr, left, right);
            log.info("返回的基准位置是:{},分区排序后的结果:{}", pivot, arr);
            // 基准元素一定比左边的数大,所以左边分区最大值是:pivot - 1,分区范围是[left, pivot - 1]
            quickSort(arr, left, pivot - 1);
            // 基准元素一定比右边的数小,所以右边分区最小值是:pivot + 1,分区范围是[pivot + 1, right]
            quickSort(arr, pivot + 1, right);
        }
    }

    public static int partition(int[] arr, int left, int right) {
        // 定义基准元素
        int pivotValue = arr[left];
        // 遍历(条件就是分区左边索引小于右边索引)
        while (left < right) {
            // 从右边right开始遍历,找到一个数比基准数小
            while (left < right && arr[right] >= pivotValue) {
                // 未找到,继续往前找
                right--;
            }
            // 找到了,则把找到小值放到此时左边索引的位置
            // 第一次进入时,基准元素已存放到临时值pivotValue了,第一次就相当于放到基准位置了,同时,arr[right]也腾出了一个位置
            arr[left] = arr[right];
            // 从左边left开始遍历,找到一个数比基准数大
            while (left < right && arr[left] <= pivotValue) {
                // 未找到,继续往后找
                left++;
            }
            // 找到了,则把找到大值放到此时右边索引的位置(也就是腾出的位置)
            // 同时,arr[left]也腾出了一个位置
            arr[right] = arr[left];
        }
        // left等于right说明遍历结束了,把基准元素插入到腾出的位置,也就是arr[left]或者arr[right]
        arr[left] = pivotValue;
        // 返回基准元素插入的位置
        return left;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{19, 28, 8, 23, 10, 21, 9};
        log.info("要排序的初始化数据:{}", arr);
        //从小到大排序
        quickSort(arr, 0, arr.length - 1);
        log.info("最后排序后的结果:{}", arr);
    }

运行结果:

要排序的初始化数据:[19, 28, 8, 23, 10, 21, 9]
开始排从【arr[0]】到【arr[6]】数据
返回的基准位置是:3,分区排序后的结果:[9, 10, 8, 19, 23, 21, 28]
开始排从【arr[0]】到【arr[2]】数据
返回的基准位置是:1,分区排序后的结果:[8, 9, 10, 19, 23, 21, 28]
开始排从【arr[4]】到【arr[6]】数据
返回的基准位置是:5,分区排序后的结果:[8, 9, 10, 19, 21, 23, 28]
最后排序后的结果:[8, 9, 10, 19, 21, 23, 28]

结语

  只要懂了前面三个部分的分区,那么你理解这个快速排序就容易了,相信我的图已经给你很好的启示了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/24342.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 Spring Boot 设置 Hibernate Envers

Hibernate Envers是一个实现持久实体的审核和版本控制的模块。审计和版本控制是构建生产级Spring 启动微服务的关键组件。Hibernate Envers与Spring Boot无缝集成以实现相同的目标。 在这篇文章中&#xff0c;我们将在我们的Spring Boot Starter应用程序中集成Hibernate Envers…

生信工作流框架搭建 | 02-nextflow 实战

目录生信工作流框架搭建 | 02-nextflow前情提要开始使用依赖安装核心概念一个fastqc的示例&#xff0c;加深理解快速搭建你的程序你需要仔细阅读的&#xff1a;可以快速浏览&#xff08;但需要知道大概有什么&#xff0c;以便后来查览&#xff09;&#xff1a;报错&#xff01;…

IPD-需求管理流程

一、产品需求管理模型 在确定客户需求时,要考虑影响用户购买标准的八类基本需求($APPEALS),并基于客户视角进行详细分解,形成有针对性的产品。 1.1、需求管理业务流程 二、需求收集流程 2.1、需求收集的来源 路标规划:通过市场管理流程分析,落实到路标规划中的需求…

基于Paddle的手写数字识别模型

百度飞桨(paddlepaddle)是百度的开源深度学习平台&#xff0c;今天就利用paddle来编写入门级的手写数字模型&#xff0e; 一&#xff0c;准备数据 下载数据集&#xff0c;这里我们使用的是MNIST数据集 # 下载原始的 MNIST 数据集并进行解压 wget https://paddle-imagenet-mode…

12.数组的初始化和引用

数组的初始化 定义数组的时候&#xff0c;顺便给数组的元素赋予初值&#xff0c;即开辟空间的同时并且给数组元素赋值 一维数组的初始化 a. 全部初始化 int a[5] {2,4,7,8,5}; 代表的意思&#xff1a;a[0] 2 , a[1] 4 , a[2] 7 , a[3] 8, a[4] 5; b. 部分初始化 int …

Clever Internet Suite for Delphi, C++Builder

为Internet应用程序添加即时SSL/TLS安全性&#xff0c;并实现许多有用的Internet相关功能。 聪明的互联网套件允许您添加下载、上传和提交互联网资源;发送和接收MIME消息;HTTP、FTP、SMTP、POP3、IMAP和NNTP客户端/服务器解决方案;带有数字证书的SSL/TLS通道支持您的VCL应用程序…

电脑分辨率怎么调?电脑分辨率怎么调合适

​无论是笔记本电脑的用户&#xff0c;还是说台式电脑的用户&#xff0c;在使用电脑的时候&#xff0c;如果电脑分辨率调整的不对&#xff0c;很容易造成显示与观感方面的模糊。电脑分辨率怎么调&#xff1f;电脑分辨率怎么调最佳&#xff1f;本篇文章&#xff0c;小编就来教教…

ASEMI肖特基二极管1N5822参数,1N5822特征,1N5822应用

编辑-Z ASEMI肖特基二极管1N5822参数&#xff1a; 型号&#xff1a;1N5822 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;40V 最大RMS电桥输入电压&#xff08;VRMS&#xff09;&#xff1a;28V 最大直流阻断电压&#xff08;VDC&#xff09;&#xff1a…

三、简单了解kafka设计原理

系列文章目录 文章目录系列文章目录一、Kafka核心总控制器Controller二、kafka高性能简单理解一、Kafka核心总控制器Controller 在Kafka集群中会有一个或者多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controller&#xff09;&#xff0c;它负责…

[ZJCTF 2019]Login--动态调试--详细版

前言 主要是因为太菜了&#xff0c;看了别人的exp&#xff0c;还是懵懵懂懂的&#xff0c;都是静态分析&#xff0c;不明白为会在改密码的时候会导致最后的getshell。今天给它动态分析整一个&#xff0c;看看到底哪里出错了。 基本原理 网上有很多介绍的&#xff0c;在这里说…

Linux学习——01 gcc编译器

一、程序构建过程 高级语言的代码无法被计算机执行&#xff0c;需要将高级语言代码编译成汇编语言&#xff0c;然后再将汇编语言翻译成机器指令&#xff0c;最后通过链接生成最后的可执行文件&#xff0c;此时该文件才可以被计算机执行。总共有四步&#xff1a; 1.1 预编译&a…

[02] BLEMotion-Kit 基于QMI8658传感器使用加速度计进行倾斜检测

文章目录1. 先修知识2. 原理&#xff08;单轴为例&#xff09;2.1 单轴倾斜2.2 双轴倾斜2.3 三轴倾斜1. 先修知识 2. 原理&#xff08;单轴为例&#xff09; 首先我们要知道的是&#xff1a;当目标轴(本例中为X轴)与地球表面平行时,传感器处于 0g 场。顺时针或逆时针旋转90 将…

springboot+java大学生西部计划志愿者岗位补助管理系统

本课题要求实现一套大学生西部计划管理系&#xff0c;系统主要包括系统个人中心、志愿者管理、岗位信息管理、补助信息管理、交流论坛、系统管理等功能模块。 为完善志愿者、岗位信息&#xff0c;应当建立健全志愿者的补助和管理机制&#xff0c;建立有效的激励机制&#xff0c…

Android Studio无法连接设备,一直显示Loading Devices...

不知道什么时候做了啥&#xff0c;从某个时间点之后&#xff0c;电脑就特别容易断开adb&#xff0c;有时候重启电脑都不管用。 一直显示"Loading Devices..."&#xff0c;拔插设备&#xff0c;重启Android Studio都没用&#xff0c;甚至重启电脑有时候也不行。 反正…

全部售罄!1,000 多个Sports Land NFT 在 24 小时内被抢空!

现在还来得及&#xff0c;抓紧时间&#xff01;&#x1f440; 在不到24小时的时间里&#xff0c;来自《Sports Land&#xff1a;足球爱好者》作品集&#xff08;2022 年 11 月 16 日发布&#xff09;的1000 多个可穿戴 NFT 已被售出&#xff01; 祝贺 Hermit Crab Game Studio …

bootstrap学习(一)

&#xff08;1&#xff09;bootstrap第一个程序 &#xff08;2&#xff09;bootstrap排版 &#xff08;1&#xff09;bootstrap第一个程序 创建boot文件夹方置bootstrap所需要的文件目录&#xff0c;拷贝过来 创建base目录&#xff0c;创建html页面&#xff1a; 引入css&#…

python复杂网络分析库NetworkX

文章目录1.Networkx简介2.图的类型&#xff08;Graphs&#xff09;3.图的创建&#xff08;Graph Creation&#xff09;4.图的属性&#xff08;Graph Reporting&#xff09;5.图算法&#xff08;Algorithms&#xff09;6.图的绘制&#xff08;Drawing&#xff09;7.数据结构8.图…

A股api交易接口文档怎么使用?

A股api交易接口是在股票量化交易中常用到的一种量化工具&#xff0c;对于它的用法&#xff0c;小编针对性的以文档的例子说明&#xff1a; 交易接口API 功能概述&#xff1a; 名称 功能 基本函数 Init API 初始化 Deinit API 反初始化 Logon 登录交易账户 Logoff 登…

年底了,接个大活儿,做一个回顾公司五年发展的总结ppt,要求做成H5网页

公司想做个五年总结 这不快年底了么&#xff0c;公司高层打算把这五年的发展历程做一次回顾巡礼&#xff0c;一方面宣扬一下公司文化&#xff0c;另一方面歌颂一下公司这五年来取得的辉煌成就&#xff0c;单纯的做个海报&#xff0c;写个公众号文章&#xff0c;或整个传统ppt在…

最强大脑记忆曲线(11)—— 30天结束第一轮复习后的操作

对于30天以后&#xff0c;结束第一轮&#xff08;6次&#xff09;复习以后&#xff0c;我们要做点什么操作呢&#xff1f; 对第一轮复习效果的评判可以是客观的&#xff0c;也可以是主观的。所谓客观的&#xff0c;是按“复习的正确率”来评判&#xff0c;大于某个值&#xff0…