手撕快速排序

news2024/11/15 11:08:17

定义

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法. 其基本思想为:任取待排序的某个元素作为基准值,按照该排序码将待排序集合分割成两个子序列, 左子序列中所有元素均小于基准值,右子序列均大于基准值,然后左右子序列重复该过程,知道所有元素都有序为止. (核心就是递归的思想,本质上它就是个递归...)

先不考虑如何找到划分的位置, 来看一下快速排序最核心的部分(递归)->

​
    //假设按照升序对array数组中[left, right)区间中的元素进行划分
    public void quickSort(int[] arr, int left, int right) {
        if(left - right >= 1) {
            return;
        }
        
        //按照基准值对array数组的[left, right)区间进行划分
        int div = partition(arr, left, right);
        
        //划分成功后以div为边界形成了左右两部分 -> [left, div), [div + 1, right)
        //递归排[left, div)
        quickSort(arr, left, div);
        
        //递归排[div + 1, right)
        quickSort(arr, div + 1, right);
    }

​

上述为快速排序递归实现的主框架, 通过代码, 我们发现:该过程与二叉树的前序遍历有异曲同工之处, 所以我们在写递归框架时可以想想二叉树的前序遍历规则即可快速写出来,后序只需要分析如何按照基准值来对区间中数据进行划分的方式即可.

两种方法

 将区间按照基准值划分为左右两半部分的常见方式有:

1.Hoare版

来看一下详细过程:

选取最左边的元素作为基准元素. 

 

右指针先向左移动,找到一个比基准值小的元素. 然后左指针向右移动,找到一个比基准值大的元素,等到两个都找到后,彼此交换.

 

重复上述过程.

 当左指针和右指针相遇时,交换相遇点与基准元素.

这样就分成了两部分.

让我们来看一下代码实现:

​
    private int partition(int[] arr, int left, int right) {
        int i = left, j = right;
        int pivot = arr[left];
        while (i < j) {
            while (i < j && arr[j] >= pivot) {
                j--;
            }
            while (i < j && arr[i] <= pivot) {
                i++;
            }
            swap(arr, i, j);
        }
        swap(arr, i, left);
        return i;
    }

​

2.挖坑法:

顾名思义:就是挖坑.  即先将第一个(最左边的数据)存放在临时变量中,这时最左边就成了"坑位", 然后移动右指针,找到一个比基准元素小的, 把它放到坑位中,此时右指针的位置就形成了一个"坑位",再移动左指针,找到一个比基准元素大的,放入右指针的"坑位中".重复上述过程即可, 直到左右指针重合.

    private int partition1(int[] arr, int left, int right) {
        int i = left, j = right;
        //确定一个基准值(第一个坑位)
        int pivot = arr[left];
        while(i < j) {
            while(i < j && arr[j] >= pivot) {
                j--;
            }
            //填左指针的坑(比基准元素小的)
            arr[i] = arr[j];
            while(i < j && arr[i] <= pivot) {
                i++;
            }
            //填右指针的坑(比基准元素大的)
            arr[j] = arr[i];
        }
        //将基准元素填入左右指针相遇的坑位
        arr[i] = pivot;
        return i;
    }

3.大声发:

 

快速排序总结

1.快速排序整体的综合性和使用场景都是比较好的,所以才敢叫快速排序.

2.时间复杂度O(N*LogN):这个东西可以类比为之前学过的归并排序,它们都是树形结构

3.空间复杂度:O(LogN)

4.稳定性:不稳定

注:快速方法有个致命的问题就是:数组越有序,时间复杂度越高,因为当它越有序时,按照之前的方法,就会把数组分成很小的小块,形成单枝的链表结构! 此时时间复杂度高达O(N^2)! 

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

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

相关文章

投后管理系统的功能模块

投后管理系统的技术难点可能包括以下几个方面&#xff0c;这些技术难点需要综合考虑&#xff0c;并结合具体的业务需求和技术实现&#xff0c;才能构建出高效、安全、稳定的投后管理系统。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…

【Python】成功解决NameError: name ‘sns‘ is not defined

【Python】成功解决NameError: name ‘sns’ is not defined &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您…

基于Java (spring-boot)的毕业作品管理系统

一、项目介绍 管理员管理设计题目&#xff0c;投票记录&#xff0c;选题信息以及公告。 教师对设计题目进行投票&#xff0c;审核并管理用户选题信息。 用户选择设计题目&#xff0c;查看选题审核状态&#xff0c;管理选题信息。 二、作品包含 三、项目技术 后端语言&#xff1…

一体式以电折水智能终端:化繁为简,智能八合一

一体式以电折水智能终端通过高度集成化设计&#xff0c;巧妙融合了空气开关、开关电源、隔离变压器、接触器、智能电表、RTU、4G通信模块、定位模块等八大核心功能&#xff0c;不仅展现了经济高效和智能运维的双重优势&#xff0c;更以其超强的安全防护能力确保了使用的高度安全…

maven打包把所有依赖的jar copy到一个文件夹

在maven项目中&#xff0c;是使用依赖坐标来引入jar包&#xff0c;在引入jar包的时候&#xff0c;maven也会默默的帮助我们导入这个jar包所依赖的jar包。 但是当我们打包项目使用jar包运行的时候&#xff0c;往往会出现缺少jar的情况&#xff1a; 如果我们一个一个添加缺少的…

对比学习(Contrastive Learning)和孪生网络(Siamese Network)的区别!

对比学习&#xff08;Contrastive Learning&#xff09;和孪生网络&#xff08;Siamese Network&#xff09;是两种常见的无监督学习方法&#xff0c;它们有着不同的原理和应用场景。 原理与目标&#xff1a; 对比学习旨在通过最小化相似样本对之间的距离&#xff0c;最大化不相…

西井科技参与IATA全球货运大会 以AI绿动能引领智慧空港新未来

3月12日至14日&#xff0c;由国际航空运输协会IATA主办的全球货运大会&#xff08;World Cargo Symposium&#xff09;在中国香港成功举办&#xff0c;这是全球航空货运领域最大规模与影响力的年度盛会。作为大物流领域全球领先的“智能化与新能源化”综合解决方案提供商&#…

从零开始写 Docker(六)---实现 mydocker run -v 支持数据卷挂载

本文为从零开始写 Docker 系列第六篇&#xff0c;实现类似 docker -v 的功能&#xff0c;通过挂载数据卷将容器中部分数据持久化到宿主机。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; …

[C++]20.实现红黑树。

实现红黑树 一.基本概念&#xff1a;1.红黑树的概念&#xff1a;2.红黑树的性质&#xff1a; 二.实现红黑树&#xff1a;1.基本结构&#xff1a;2.插入节点的多种情况&#xff1a;1.叔叔存在且为红&#xff1a;2.叔叔不存在/存在且为黑(单旋变色)3.叔叔不存在/存在且为黑(多旋&…

【计算机网络篇】计算机网络的定义和分类

文章目录 &#x1f354;什么是计算机网络&#x1f5c3;️计算机网络的分类⭐按交换方式分类⭐按使用者分类⭐按传输介质分类⭐按覆盖范围分类⭐按拓扑结构分类 &#x1f6f8;小结 &#x1f354;什么是计算机网络 计算机网络是指将多台计算机或其他网络设备通过通信链路连接起来…

C语言 ——常量

3, 常量 3.1 什么是常量 ​ 程序运行的过程中&#xff0c;其值永远不会发生改变的数据 3.2 常量的分类 3.3 练习 ​ 给你一组数据&#xff0c;说出下面每组数据中&#xff0c;分别是哪种类型的常量 3.4 细节补充 实型常量的小细节&#xff1a; * 小数点前后&#xff0c;如果…

【数据结构】二叉树---AVL树的实现

目录 一. 什么是AVL树 二. AVL树的结点结构定义 三. AVL树的动态平衡法 1. 左单旋转 --- RL(RotateLeft) 型调整操作 2. 右单旋转 --- RR(RotateRight) 型调整操作 3. 先左后右双旋转 --- RLR (RotateLeftRight) 型调整操作 4. 先右后左双旋转 --- RRL (RotateRightL…

python工具方法 47 基于paddleseg将目标检测数据升级为语义分割数据

在进行项目研究时,通常需要搜集开源数据集。但是所能搜集到的数据集通常会存在形式上的差异,比如我想要的是语义分割数据,而搜集到的数据集却是目标检测数据;在这种情况下所搜集的数据就完成没有利用价值了么?不,其还存在价值,我们可以通过模型训练对数据标签的标注粒度…

【学习】python装饰器

这篇文章讲的太清楚了&#xff01;非常好好好&#xff01;&#xff01;&#xff01;Python】一文弄懂python装饰器&#xff08;附源码例子&#xff09; 在他的基础上加了一些自己的话&#xff0c;便于自己理解。 注意的点&#xff1a; func 表示函数对象&#xff0c;可以将其…

智慧公厕建设,助力打造宜居、韧性、可持续的智慧城市

公共厕所作为智慧城市的重要组成部分&#xff0c;对于城市的高质量发展起着至关重要的作用。智慧公厕建设旨在通过全面监测、控制和管理公共厕所&#xff0c;实现多方面功能&#xff0c;包括公共厕所环境监测与调控、厕位占用监测与引导、消耗品监测与缺失提示、安全防范与管理…

使用OCC进行旋转扫掠

旋转扫掠是将物体以某一个坐标轴为参照&#xff0c;按照指定的角度旋转生成新的图形的过程 这里使用面的案例&#xff0c;使用线的逻辑处理其实是一样的 //构造旋转轴 gp_Ax1 anAxis; //设置轴的原点 anAxis.SetLocation(0,0,0); //设置轴的方向 anAxis.SetDirection(gp_Dir(0…

N3-Chitosan N3 叠氮修饰壳聚糖 改性叠氮 CS-Azide

碳水科技&#xff08;Tanshtech&#xff09;可以提供壳聚糖衍生物 1.壳聚糖的各种改性(NH2/COOH/SH/N3/MAL-Chitosan等) 2.各种靶向小分子修饰壳聚糖&#xff08;Biotin/FA/cRGD-Chitosan等&#xff09; 3.各种荧光标记壳聚糖(FITC/RB/CY-Chitosan等) 4.壳聚糖和各种聚合物…

基于springboot实现数据资产管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现数据资产管理系统演示 摘要 固定资产管理系统主要是完成对系统用户管理、资产信息管理、资产变更管理、资产用途管理、资产类别管理和资产增减管理。因为利用本系统管理员可以直接录入信息&#xff0c;修改信息&#xff0c;删除信息&#xff0c;并且若在录入…

【学一点RISC-V】RISC-V IMSIC

IMSIC RISC-V AIA 文档 第三章 Incoming MSI Controller (IMSIC) 传入 MSI 控制器&#xff08;IMSIC&#xff09;是一个可选的 RISC-V 硬件组件&#xff0c;与 hart 紧密相连&#xff0c;每个 hart 有一个 IMSIC。IMSIC 接收并记录 Hart 的传入消息信号中断 (MSI)&#xff0c;并…

Ubuntu下txt中文显示乱码问题常规解决方法

在正常使用ubuntu 文档时&#xff0c;突然发现txt文档出现&#xff0c;如下情况 无法正常观看&#xff0c;后来搜了一下发现是gedit 没有对应打开文件的编码格式&#xff0c;Ubuntu用的是utf-8,所以打开会有乱码&#xff01;初始没有GBK和GB2312&#xff0c;把GBK和GB2312添加…