算法通关村-----快速排序的原理和实现

2023-11-15

快速排序介绍

快速排序是一种经典高效的排序方法,是分治策略在排序上的具体体现。将一个大的待排序列分割成若干个小的有序序列,最终将各个小的有序序列合并成一个大的有序序列。

快速排序的实现原理

选择一个基准值,将小于基准值的元素放在基准值左侧,大于基准值的元素放在基准值右侧,基准值放在中间。基准值可以选择待排序列的第一个元素,最后一个元素,中间元素,也可以选择三者的中位数提高快排效率。一轮快速排序后,基准值已经有序,之后对基准值两侧的数据分别进行快排,这是一个递归的过程,最终整个序列有序。整个过程类似于树的前序遍历,每一轮的过程使用双指针,所以快排本质上是树的前序遍历+双指针。

快速排序的具体实现

基准值选择不同,代码实现不同,但本质上都是树的前序遍历+双指针

选择第一个元素作为基准值代码实现

代码实现

public void quickSort(int[] array, int left, int right) {
    if (left < right) {
        int pivot = array[left];
        int i = right + 1;
        for (int j = right; j > left; j--) {
            if (array[j] > pivot) {
                i--;
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
        int pivotIndex = i - 1;
        int temp = array[pivotIndex];
        array[pivotIndex] = array[left];
        array[left] = temp;
        quickSort(array, left, pivotIndex - 1);
        quickSort(array, pivotIndex + 1, right);
    }
}

选择最后一个元素作为基准值代码实现

代码实现

public void quickSort(int[] array, int left, int right) {
    if (left < right) {
        int pivot = array[right];
        int i = left - 1;
        for (int j = left; j < right; j++) {
            if (array[j] < pivot) {
                i++;
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
        int pivotIndex = i + 1;
        int temp = array[pivotIndex];
        array[pivotIndex] = array[right];
        array[right] = temp;
        quickSort(array, left, pivotIndex - 1);
        quickSort(array, pivotIndex + 1, right);
    }
}

选择中值作为基准值代码实现

代码实现

public static void quickSort(int[] array, int start, int end) {
    if (start >= end) {
        return;
    }
    int left = start;
    int right = end;
    int mid = (left + right) / 2;
    int pivot = array[mid];
    while (left <= right) {
        while (left <= right && array[left] < pivot) {
            left++;
        }
        while (left <= right && array[right] > pivot) {
            right--;
        }
        if (left <= right) {
            int temp = array[left];
            array[left] = array[right];
            array[right] = temp;
            left++;
            right--;
        }
    }
    quickSort(array, start, right);
    quickSort(array, left, end);
}

快速排序复杂度分析

时间复杂度:

平均情况下:O(n log n)。在平均情况下,快速排序通常具有优秀的性能。每次分割都将数组分为两部分,每部分的大小约为原数组的一半。因此,在进行 log n 次递归后,每个子数组都会被完全排序,总的时间复杂度是 O(n log n)。

最坏情况下:O(n^2)。最坏情况发生在选择基准值不平衡的情况下,导致每次分割只能减少一个元素。例如,如果数组已经有序或接近有序,且始终选择第一个元素作为基准值,那么就会出现最坏情况。为了避免最坏情况,可以使用随机选择基准值或者三数取中法等策略。

最好情况下:O(n )。最好情况发生在数组有序

空间复杂度

快速排序是一种原地排序算法,不需要额外的内存空间,因此其空间复杂度是 O(1)。

稳定性

快速排序是不稳定的排序算法,即相等元素的相对顺序可能在排序后改变。

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

算法通关村-----快速排序的原理和实现 的相关文章

随机推荐

  • 第几个幸运数

    暴力 include
  • Vue中的验证登录状态

    Vue项目中实现用户登录及token验证 先说一下我的实现步骤 使用easy mock新建登录接口 模拟用户数据 使用axios请求登录接口 匹配账号和密码 账号密码验证后 拿到token 将token存储到sessionStorage中
  • git撤回某次commit

    假设我们已经将本地代码提交到远程分分支上 但是我们想撤回某一个commit或者是对某一个文件的修改进行撤回等操作 我们可以使用以下这几种方式 一 git reset git reset 回滚到某次提交 git reset mixed 此次提
  • 数据库系统原理------ER图转化成关系模式

    E R图转换 E R图是由实体 实体的属性和实体之间的联系三个要素组成的 将E R图转换为关系模型实际上就是要将实体 实体的属性和实体之间的联系转化为关系模式 实体集向关系模式的转换 一般转换遵循的原则 实体集的转换规则 一个实体型转换为一
  • 特网科技云服务器适合安装那些操作系统

    通过云主机 择带有预装控制面板的模板 只需单击几下即可安装 可用的操作系统模板 我们在管理虚拟服务器时使用的主要操作系统是Ubuntu Debian Windows CentOS Kali Astra Orel CentOS Communi
  • unity+vuforia+二维码识别

    Easy Code Scanner 下载地址 Easy Code Scanner v2 3 本文转载自http blog csdn net puremilk684 article details 51479245 经本人验证 可以在安卓平台
  • .NET使用MQTT通信实例

    最近项目里面需要用到MQTT 刚开始听到这个词一脸茫然 不知道是什么 最后通过自己百度整理一点资料 希望最大家有帮助 在这里需要引用MQTTnet 可在解决方案在右键单击 选择 管理解决方案的 NuGet 程序包 在 浏览 选项卡下面搜索
  • AttributeError: module ‘tensorflow‘ has no attribute ‘Session‘

    代码错误 Traceback most recent call last File D PyCharm PythonProject DRL Networking master DRL Networking master IPDPS2020
  • Real-Time Rendering——9.11 Wave Optics BRDF Models波动光学BRDF模型

    The models we have discussed in the last few sections rely on geometrical optics which treats light as propagating in ra
  • 在Linux中安装nodejs(未编译版安装方法)

    技术背景 Linux安装 nodejs 总的来说 有两种方法 第一种是安装未编译版本 然后自行编译在安装 第二种是直接安装编译版本 推荐 但作为笔记 我两种都得写 那种适合自己 自行挑选 废话不多说 我们直接上步骤 第一步 执行 wget
  • vue.js—定义全局变量、函数

    废话不多说 直接上代码 以便以后学习查看 一 全局变量 原理 1 单独新建一个全局变量模块文件 模块中定义一些变量初始状态 用export default 暴露出去 2 在main js中引入 并通过Vue prototype挂载到vue实
  • Fragment生命周期

    http blog csdn net forever crying article details 8238863 官网帮助文档链接 http developer Android com guide components fragments
  • WindowsFormsHost控件

    WPF和WinForms是两个不同的UI框架 都是由Microsoft创建的 WPF是WinForms的一个更现代的替代品 WinForms是第一个 NET UI框架 为了在两者之间轻松过渡 Microsoft确保WinForms控件仍然可
  • 我的编程语言经历

    Alan Perlis 说过 一种不改变你编程的思维方式的语言 不值得去学 虽然写了这么多年程序 用了这么多的语言 但我自认还没悟道编程语言如何改变我的思维方式 几天前 我需要用python来为 ledisdb 写一个客户端 我突然发现 对
  • adc读出的数据和输入电压不匹配

    1 参考电压输入有误 1 stm8和stm32 模拟电源输入的电压有问题 或者精度设置出错 导致最终电压参考有误 最终adc值出错 2 华大的芯片还多了一种可能 就是adc的参考源选择错误 可选的参考源包括内部1 5v参考 2 5v参考 外
  • 创业小记:终于开发了个有点希望的产品了

    过了3个月了 做了8个产品 有一个产品 有点起色 在7月有290刀的收入 3个月时间了 打算简单复盘一下 一个字 抄 二个字 参考 三个字 微创新 我是个典型的技术同学 我不建议跟我一样背景的人从开发自己有需求的产品开始 这是主流论调 就是
  • Java JDBC (MySQL5.7)

    文章目录 第一章 JDBC简介 1 JDBC的好处 第二章 JDBC使用 1 使用步骤 2 普通方式实现代码 3 优化为工具类 4 使用数据库连接池Druid 第三章 参考资料 第一章 JDBC简介 Java DataBase Connec
  • mysql distinct和order by 一起用时,order by的字段必须在select中

    原因 1 首先 在MySQL中 distinct 的执行顺序高于 order by 2 第二 distinct 执行时会对查询的记录进行去重 产生一张虚拟的临时表 3 第三 order by 执行时对查询的虚拟临时表进行排序 产生新的虚拟临
  • Windows下MySQL免安装版的下载与配置

    因为自己学习开发的需求 需要在本地安装MySQL数据库用来做本地测试 对于个人开发者 可以下载MySQL Community Server版本 该版本是免费的 安装和配置方法如下 MySQL Server下载地址 https dev mys
  • 算法通关村-----快速排序的原理和实现

    快速排序介绍 快速排序是一种经典高效的排序方法 是分治策略在排序上的具体体现 将一个大的待排序列分割成若干个小的有序序列 最终将各个小的有序序列合并成一个大的有序序列 快速排序的实现原理 选择一个基准值 将小于基准值的元素放在基准值左侧 大