算法入门之最常用的排序:快速排序算法

2023-10-27

回顾前面2篇文章我们提到了桶算法和冒泡算法,虽然冒泡算法解决了桶算法的空间问题,但是如果排序的基数比较大,你会发现冒泡算法的时间复杂度O(N²)也是惊人的,有没有一种更好的算法既能解决空间问题又能解决时间复杂度的问题呢?答案就是我们今天要说的:快速排序算法

 

先上代码实现:

public class QuickSort {

    public static int[] sort(int[] waitNumbers, int start, int end) {
        // 当开始下标大于等于结束下标时,递归结束 返回排序后的结果
        if (start >= end) {
            return waitNumbers;
        }
        int i = start; //左边哨兵 初始值
        int j = end; //右边哨兵 初始值
        int t;  // 临时变量 交换值用的
        int temp = waitNumbers[start]; //存放基准数

        //循环执行直到开始下标 大于等于 结束下标时为止,
        //说明此轮排序结束,交换基准值,再次执行排序
        while (i < j) {
            /**
             * 右边下标先开始扫描 直到扫描到比基准数小的数为止,
             * 思考:为什么一定是j先开始扫描?
             * 解:因为我们要满足比基准数小的在左边,如果i先开始
             *   扫描,会出现i大于基准数的情况,为了满足i所在的值
             *   一定要小于基准数,我们必须先从右边开始扫描
             *   当j和i相交时,一定是j找到了比基准值小的数,如果
             *   是i先开始,可能会当i找到了比基准值大的时候,j还
             *   没找到比基准值小的,这个时候交换的不是i j的值,
             *   而是i和基准值的值,此时出现了比基准值大的值跑到
             *   基准值左边去了
             */
            while (waitNumbers[j] >= temp) {                        
                j--;
            }
            // 左边下标开始往右扫描。直到扫描到比基准数大的数为止
            while (waitNumbers[i] <= temp && i < j) {
                i++;
            }
            // 当i找到比基准数大,j找到比基准数小的时候,
                  // 交换i和j下标的值 继续往下执行,直到i>=j
            if (i < j) {
                t = waitNumbers[i];
                waitNumbers[i] = waitNumbers[j];
                waitNumbers[j] = t;
            }
        }
        // 交换基准值
        waitNumbers[start] = waitNumbers[i];
        waitNumbers[i] = temp;
        // 递归调排序执行基准值左边的值
        sort(waitNumbers, start, i - 1);
        // 递归调排序执行基准数右边的值
        sort(waitNumbers, i + 1, end);
        return waitNumbers;
    }

    public static void main(String[] args) {
        // 待排序的数字
        int[] waitNumbers = {8, 15, 3, 13, 6, 35, 45, 2, 10};
        QuickSort.sort(waitNumbers, 0, waitNumbers.length - 1);
        System.out.println(JSON.toJSONString(waitNumbers));
    }
}
结果:[2,3,6,8,10,13,15,35,45]

 

分析:思路分析已经在代码中分析很明确,这里就不再说了,既然这种算法能有效解决冒泡算法时间复杂度的问题,那么我们就来分析下

快速排序为什么比冒泡排序速度要快?

解:我们都知道冒泡排序是每次将相邻两个数进行比较和交换,而快速排序是每次设置一个基准点,将小于基准点的数放在左边,大于基准点的数放右边,每次交换的就不是相邻的两个数了,交换的距离大了,总的交换次数也少了,当然速度也就比冒泡排序快了,这种算法有没有一种似曾相识的感觉,如果有,那就对了,那就是二分查找思想,当然这不是二分查找,不要混淆。

 

快速排序算法的时间复杂度?

平均时间复杂度:快速排序算法的时间复杂度是跟原始数据的顺序有密切关系的,基准值显得特别重要了,我们了解到快速排序之所以快,是因为他可以从基准值的左边两边同时递归排序下去,所以最理想的状态就是基准值处于原始无序数据的中间,这样能最大效率让两边排序,同时减少递归划分出的区域,此时时间复杂度为O(NlogN),即平均时间复杂度;

最差时间复杂度:还有一种最差的情况就是每次作为基准值的数刚好是数组中最小/最大的那个数,此时其实就相当于冒泡,每次排好一个元素位置,所以最差时间复杂度等于冒泡算法时间复杂度O(N²)

 

优点:时间复杂度小,效率高,速度快

缺点:对于越是有序的数组排序效率越低

 

学习了三种排序算法我们做个简单的总结:

 桶算法:速度最快O(M+N),占空间最大O(N),适合基数小的正整数排序,

                适合先去重后排序的场景

 冒泡算法:速度最慢,占空间最小O(1),最稳当

 快速排序算法:速度优于冒泡O(NlogN),占优于桶O(log2n)~O(n),

                          稳定性次于冒泡

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法入门之最常用的排序:快速排序算法 的相关文章

  • ZigBee节点——ZigBee协议栈Z-Stack开发指南

    ZigBee节点 ZigBee协议栈Z Stack开发指南 分类 ZigBee 2011 08 18 14 06 749人阅读 评论 0 收藏 举报 网络 路由器 终端 network types 通讯 1 1设备类型 Device Typ
  • STM32实战项目—楼宇人员计数系统

    本文项目比较简单 目的是介绍一下红外对管的使用 程序设计也比较简单 因此 博主并没有将程序工程上传资源 如果有需要的话可以私信 文章目录 一 任务要求 二 实现方法 2 1 红外对管简介 2 2 进出人员检测 三 程序设计 3 1 红外对管
  • Intellij idea 报错:Error : java 不支持发行版本5

    推荐解决方式 感谢评论区另一位博友 Fumoon 提供的方案 https blog csdn net qq 42583206 article details 108375173 如按上述方式解决了问题 下文可以忽略
  • webrtc opus 设置与编码

    webrtc opus bg57iv3 扩展头 格式 audio encoder Received session description sdp v 0 o 7489544636758395528 2 IN IP4 127 0 0 1 s
  • 【JustPlay】Brushless ESC calibration

    PWM frequency 50Hz High level time for full throttle 2ms High level time for zero throttle 1ms Brushless ESC calibration
  • TansUNet代码理解

    首先通过论文中所给的图片了解网络的整体架构 vit seg modeling部分 模块引入和定义相关量 coding utf 8 future 在老版本的Python代码中兼顾新特性的一种方法 from future import abso
  • snort在windows下的安装配置

    环境 win7 snort2 8 6 1 安装npcap或者winpcap 首先安装npcap 这是因为snort对网络数据包进行捕获 需要npcap 2 安装snort 使用安装包安装snort 这里直接向下安装即可 不过需要注意snor
  • 数字化转型建设的基本模型与能力构建

    数字经济的政策推动下 行业数字化转型建设如火如荼 本文提出了一种业务为主线的数字化转型建设的基本模型 数据应用业务链 并以数据应用业务链的业务的数据 数据的业务 业务的业务这三个环节探讨了数字化转型建设的能力构建及其基本过程并划分了可合作的
  • 关于激光雷达盲区0.4m问题

    https xw qq com amphtml 20220302A03F6I00 盲区 吸点 激光雷达探测器一般有几到几十纳秒的Dead Time Dead Time指是接收到一个激光脉冲后到再能接受一个新激光脉冲所需的最短时间 当一束激光
  • uniapp 微信小程序订阅(一次性订阅消息)

    首先我们需要了解微信小程序的一些基本的 才能知道我们要做什么 微信小程序消息订阅只有两种形式可以召唤出来 1 用户手动点击按钮 2 支付回调唤起 一次调用最多可订阅3条消息 小程序弹出后 可点击的情况 1 单纯点击取消 确认键 2 勾选了总
  • ajax降低性能,AJAX的性能改进

    AJAX的性能改进 简介 在Web窗体中 我们使用AJAX来从客户端 从JavaScript 调用服务器端方法 AJAX的内部使用XMLHttpRequest 我已经测试了不同的方式实现Ajax功能 另外 我有监测AJAX调用的性能和生命周
  • Introduction to NMOS and PMOS Transistors

    原文链接 https anysilicon com introduction to nmos and pmos transistors Introduction to NMOS and PMOS Transistors In this ar
  • 【网课平台】Day10.对接第三方:实现微信扫码登录

    文章目录 一 需求 微信扫码登录 1 接口文档 2 开发环境准备 3 接入分析 4 接口定义 5 申请令牌 6 查询用户信息 7 保存用户信息 一 需求 微信扫码登录 和第三方对接的流程 1 接口文档 找到第三方的接口文档 微信扫码登录 可

随机推荐

  • 基于python的爬虫实现

    定义 爬虫 Web crawler 也被称为网络爬虫 网络蜘蛛或网络机器人 是一种自动化程序 用于浏览互联网并收集网页内容 基本原理 爬虫的工作原理是通过发送HTTP请求从网页服务器获取网页的内容 然后解析网页并提取所需的数据 具体步骤如下
  • 让vscode正确识别webpack alias路径的方法

    一般的相对路径引入依赖文件 vscode能够正确识别 做出智能提示 但是有时候项目目录层级太深 写相对路径很长 非常容易出错 所以一般我们会在webpack中配置alias 使用短名来减少路径层级 如 import getUsers fro
  • 国内网络摄像机的端口及RTSP地址

    海康威视 默认IP地址 192 168 1 64 DHCP 用户名admin 密码自己设 端口 HTTP 端口 默认为 80 RTSP 端口 默认为 554 HTTPS 端 口 默认 443 和 服务端口 默认 8000 ONVIF端口 8
  • 揭秘阿里新一代SpringCloud学习指南:掌握最具中国特色的微服务组件

    SpringCloud Alibaba 的优势 阿里使用过的组件经历了考验 性能强悍 设计合理 现在开源出来给大家用 成套产品搭配完善的可视化界面给开发运维带来了极大的便利 搭建简单 学习曲线低 作为国内微服务领域的领军企业 阿里巴巴在微服
  • 自定义设置一个屏保程序

    用C语言写一个简单的窗口程序 目的是生成一个可视化的图形窗口 需要用到EasyX库 可在文章末尾的网盘链接中下载 该程序退出需左击鼠标 否则无法退出 include
  • Learning_the_shell

    昨天逛了www linuxcommand org 学习了shell的基本知识 对alias function type等基本命令有了比较深入的了解 还有就是对top kill ps jobs等进程命令有了更清晰的了解 特别是kill的参数问
  • MRI T1加权结构

    MRI是多参数成像 出于分析图像的方便 希望一帧MRI图像的灰度主要由一个特定的成像参数决定 这就是所谓的加权图像 weighted imaging WI 例如图像灰度主要由T1决定时就是T1加权图像 主要由T2决定时就是T2加权图像 主要
  • ubuntu18.04安装caffe(cpu版)

    主要根据ubuntu安装caffe这个博客 网上有些教程说要安装protobuf2 6 1 实际上只要有protobuf就行 版本无所谓 如果编译过程中出现google protobuf未定义的引用之类的报错 可能是protobuf版本和g
  • Python 类中pass语句

    Python pass 是空语句 是为了保持程序结构的完整性 pass 不做任何事情 一般用做占位语句 本文主要介绍Python 类中pass语句 原文地址 Python 类中pass语句
  • 普氏分析 matlab,降维和特征提取 - MATLAB & Simulink - MathWorks 中国

    特征选择 Learn about feature selection algorithms and explore the functions available for feature selection This topic intro
  • 10 分钟上手 Vue 组件 Vue-Draggable

    Vue 综合了 Angualr 和 React 的优点 因其易上手 轻量级 受到了广泛应用 成为了是时下火热的前端框架 吸引着越来越多的前端开发者 本文将通过一个最简单的拖拽例子带领大家快速上手 Vue 组件 Vue Draggable 首
  • 使用()控件的saveas方法可以将上传文件保存到服务器.,3.25.1 使用FileUpload控件上传文件...

    VB Protected Sub Button1 Click ByVal sender As Object ByVal e As System EventArgs If FileUpload1 HasFile Then Try FileUp
  • Android禁用第三方应用

    需要权限android Manifest permission CHANGE COMPONENT ENABLED STATE 而这个权限是只有system app才能使用 所以app需要系统签名 非system app即便在Android
  • Java中使用到的异步任务总结(CompletableFuture类,@Async注解)

    文章目录 1 CompletableFuture 1 1 Completable supplyAsync 1 2 Completable runAsync 1 3 get方法 1 4 使用自定义线程池 1 5 Completable all
  • LaTex

    LaTex LaTex 前言 一 安装配置LaTex 版本安装介绍 配置使用的IDE 二 简单的论文配置问题 基本的语法 1 文档类型和开始 2 最基础的格式化命令 3 Chapters and Sections 文章的章节 4 添加图片
  • 大学物理实验:迈克尔逊干涉仪的调整与使用

    若本文对你有帮助 记得点赞 关注我哟 大学物理专栏https blog csdn net qq 41587612 category 9323622 html
  • Java图形化界面设计之容器(JFrame)详解

    Java图形化界面设计之容器 JFrame 详解 Java图形化界面设计 容器 JFrame 程序是为了方便用户使用的 因此实现图形化界面的程序编写是所有编程语言发展的必然趋势 在命令提示符下运行的程序可以让我们了解java程序的基本知识体
  • kvm的快照功能 (二、基于libvirt的快照)

    实例二 利用libvirt使用快照 virsh snapshot create domain name 一 创建虚机快照 名字自动生成 可在开机 关机 suspend等各种状态下做 virsh snapshot create test Do
  • 【TensorFlow 入门】6、eval 函数

    eval 其实就是tf Tensor的Session run 的另外一种写法 但两者有差别 eval 将字符串string对象转化为有效的表达式参与求值运算返回计算结果 eval 也是启动计算的一种方式 基于Tensorflow的基本原理
  • 算法入门之最常用的排序:快速排序算法

    回顾前面2篇文章我们提到了桶算法和冒泡算法 虽然冒泡算法解决了桶算法的空间问题 但是如果排序的基数比较大 你会发现冒泡算法的时间复杂度O N 也是惊人的 有没有一种更好的算法既能解决空间问题又能解决时间复杂度的问题呢 答案就是我们今天要说的