Python实现快速排序

2023-11-11

Python实现快速排序

一、快速排序简介

快速排序(Quick Sort)是一种效率很高的排序算法,是对冒泡排序的一种改进排序算法。

快速排序首先任意选取一个数据(通常选待排序列表中的第一个数)作为基准数据,将待排序列表中的数据分割成独立的两部分,所有比基准数据小的数都放到它左边,所有比基准数据大的数都放到它右边,此时基准数据排序完成,第一轮快速排序完成。然后再按此方法对两部分的数据分别进行快速排序,整个排序过程可以递归进行,直到被分割的数据只有一个或零个时,递归结束,列表排序完成。

快速排序的名字起得简单直接,因为这种排序算法速度快,效率高,是处理大数据最快的排序算法之一。

二、快速排序原理

快速排序的原理如下:

1. 从待排序列表中选取一个基准数据(通常选取第一个数据)。

2. 将待排序列表中所有比基准数据小的元素都放到基准数据左边,所有比基准数据大的元素都放到基准数据右边(升序排列,降序反之)。用基准数据进行分割操作后,基准数据的位置就是它最终排序完成的位置,第一轮排序完成。

3. 递归地对左右两个部分的数据进行快速排序。即在每个子列表中,选取基准,分割数据。直到被分割的数据只有一个或零个时,列表排序完成。

以列表 [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] 进行升序排列为例。列表的初始状态如下图。

要进行升序排列,则每轮排序都将比基准数据小的数据放在左边,比基准数据大的数据放在右边。

1. 从待排序列表中任意选一个数据作为基准数据 mid_data,然后设置两个游标 left 和 right,分别指向列表的起始数据和末尾数据。将游标right的数据与基准数据比较,如果大于或等于基准数据,则right往左移动。基准数据为10,21大于10,right左移。

2. 当游标right的数据小于基准数据时,right停止移动,将游标right指向的数据赋值给游标left。然后将游标left的数据与基准数据比较,如果小于基准数据,则left往右移动。right移动到5时小于10,停止移动并将5赋值给left,left开始右移。

3. 当游标left的数据大于或等于基准数据时,left停止移动,将游标left指向的数据赋值给游标right。然后将游标right的数据与基准数据比较,如果大于或等于基准数据,则right往左移动。left移动到17时大于10,停止移动并将17赋值给right,right开始左移。

4. 重复步骤2,right移动到7时小于10,停止移动并将7赋值给left,left开始右移。

5. 重复步骤3,left移动到50时大于10,停止移动并将50赋值给right,right开始左移。

6. 当left与right相遇时,移动结束,将基准数据10赋值给相遇的位置,此时第一轮排序完成,列表被基准数据分割成了两个子列表,基准数据10的位置就是排序完成时的位置。

7. 递归地对分割的两个子列表进行相同的操作。以左表为例,取第一个数据5作为基准数据,设置两个游标left和right指向子表的起始和末尾,将游标right的数据与基准数据比较,如果大于或等于基准数据,则right往左移动。

8. 左表中只有两个数据,经过一次移动,left和right就相等了,移动结束,左表排序完成。对右表也使用相同方法进行递归,这里就不再赘述了。

9. 继续进行多轮递归排序,每一轮当子表只有一个或零个数据时(left>=right),递归结束。排序结果如下图。

三、Python实现快速排序

# coding=utf-8
def quick_sort(array, start, end):
    if start >= end:
        return
    mid_data, left, right = array[start], start, end
    while left < right:
        while array[right] >= mid_data and left < right:
            right -= 1
        array[left] = array[right]
        while array[left] < mid_data and left < right:
            left += 1
        array[right] = array[left]
    array[left] = mid_data
    quick_sort(array, start, left-1)
    quick_sort(array, left+1, end)


if __name__ == '__main__':
    array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
    quick_sort(array, 0, len(array)-1)
    print(array)

运行结果:

[5, 7, 10, 15, 17, 21, 24, 27, 30, 36, 45, 50]

在代码中,先将列表中的第一个数据作为基准数据mid_data,设置两个游标left和right分别标记待排序列表起始和末尾的数据。然后按照上面分析的步骤,left和right两个游标交替向中间移动,当left与right相遇时,将mid_data赋值给相遇位置的索引。此时完成了分割,mid_data左边子表中的数据都小于基准数据,右边子表中的数据都大于基准数据,第一轮排序完成。然后递归对左右两个子列表执行相同操作,递归结束的条件就是列表的长度小于2时(start>=end),此时直接返回。

快速排序除了需要传入待排序列表以外,还需要传入排序的开始索引和结束索引,也就是说快速排序可以指定排序列表中的部分数据,在递归的时候就是排序部分数据。

快速排序也可以使用非递归的方式实现,在非递归实现时,代码思路不变,但必须借助栈或队列,代码会稍微长一点。

四、快速排序的时间复杂度和稳定性

1. 时间复杂度

在快速排序中,最坏的情况是元素列表的初始状态是完全逆序排列的,这使得每次分割所得的子表中一个为空表,另一个的长度为原表的长度减1,所以需要进行 n 轮分割,每一轮需要进行 n/2 次比较。时间复杂度为 T(n)=n(n-1)/2 ,再乘每次操作的步骤数(常数,不影响大O记法),所以快速排序的时间复杂度为 O(n^2) 。

与时间复杂度是 O(n^2) 的其他排序算法相比,为什么快速排序的效率会比其他排序算法高呢?因为时间复杂度计算的是最坏情况的时间复杂度,但最坏的情况并不常见。快速排序的最优时间复杂度是 Ο(nlogn) ,很容易改变取基准数据的方法避免最坏情况的发生(如“三者值取中”),去接近最优时间复杂度。

2. 稳定性

在快速排序中,每轮排序会将数据与基准数据进行比较和分割。如果有相等的数据,可以自己决定将相等的数据放在左边还是右边(上面的代码是右边),不会影响排序结果。

在快速排序的实现过程中,有两个游标从列表的两边向中间移动,游标right向左移动的过程中,如果数据小于基准数据,则会将数据赋值给left游标。在这个过程中,如果有相等的数据,相对位置很可能会发生变化,如 [10, 5, 5] 。所以快速排序是一种不稳定的排序算法。

 

 

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

Python实现快速排序 的相关文章

  • 教你解决禁止F12、调试Debugger、丑化JS等反爬

    1 前言 在爬取数据时 有一些网站设置了反爬 禁止F12 网页调试Debugger 丑化Js 比如下面这几种情况 1 禁止查看源代码 2 网页调试Debugger 上面禁止查看网页问题 可以先按F12 再访问网站 但是又有网页调试Debug
  • Python实现桶排序

    Python实现桶排序 一 桶排序简介 桶排序 Bucket sort 是一种通过分桶和合并实现的排序算法 又被称为箱排序 桶排序先将数据分到有限数量的桶里 然后对每一个桶内的数据进行排序 桶内排序可以使用任何一种排序算法 如快速排序 最后
  • C语言实现冒泡排序和快速排序

    写在前面的话 以排升序为例 目录 冒泡排序 单趟 循环 优化 快速排序 单趟 递归 优化 不足 冒泡排序 通过重复地走访过要排序的元素列 依次比较两个相邻的元素 如果顺序错误就把他们交换过来 走访元素的工作是重复地进行 直到没有相邻元素需要
  • 两种快速排序的实现(C语言)

    两种搜索方式不一样 第 0种单向搜索 第1 种双向搜 代码如下 include
  • 数据结构之排序:快速排序

    快速排序 Quick Sort 由 C A Hoare 在1962年提出 是冒泡排序的一种改进 采用了分治策略 将原问题划分成若干个规模更小但与原问题相似的子问题 然后递归方法解决 合并问题的解 基本思想 通过一趟排序将序列分割成独立的两个
  • 排序算法(4)----快速排序

    快速排序由C A R Hoare在1962年提出 它的基本思想是 通过一趟排序将要排序的数据分割成独立的两部分 其中一部分的所有数据都比另外一部分的所有数据都要小 然后再按此方法对这两部分数据分别进行快速排序 整个排序过程可以递归进行 以此
  • C++:快速排序法的代码实现

    快速排序法 快速排序法 quick sort 的基本思想是 通过一趟排序将要排序的记录分割成独立的两部分 其中一部分的所有记录关键码比另外一部分的记录关键码都要小 然后再按此方法对这两部分数据分别进行递归快速排序 从而使序列成为有序序列 设
  • 常见的排序算法总结

    排序简介 简介 排序算法 英语 Sorting algorithm 是一种将一组特定的数据按某种顺序进行排列的算法 排序算法多种多样 性质也大多不同 性质 稳定性 稳定性是指相等的元素经过排序之后相对顺序是否发生了改变 拥有稳定性这一特性的
  • Python Tree库绘制多叉树的用法介绍

    Python Tree库绘制多叉树的用法介绍 Tree 库是一个 Python 的第三方库 这个库主要用于生成树和绘制树的图形 一 安装Tree pip install Tree 使用 Tree 库需要配合 PIL 库来实现绘图 二 官方案
  • 时间复杂度-线性对数时间nlogn的一些研究

    文章目录 排序算法的时间复杂度 二叉树与 n l o g 2 n
  • 排序算法总结(Python版)

    经典排序算法总结与实现 经典排序算法在面试中占有很大的比重 也是基础 为了未雨绸缪 这次收集整理并用Python实现了八大经典排序算法 包括冒泡排序 插入排序 选择排序 希尔排序 归并排序 快速排序 堆排序以及基数排序 希望能帮助到有需要的
  • CH8-排序

    文章目录 1 基本概念和排序方法概述 1 1 排序方法的分类 1 2 存储结构 顺序表 2 插入排序 2 1 插入排序的种类 直接插入 折半插入 希尔排序 3 交换排序 3 1 冒泡排序 3 2 快速排序 4 选择排序 4 1 直接排序 4
  • 十大经典排序算法最强总结

    点击上方 我要学编程 选择 置顶 星标公众号 福利干货 第一时间送达 排序算法属于经典基础算法基本功 笔试面试基本都会涉及和考察的 有原题也有变化 不过基础的几大排序算法还是得尽可能熟悉 能在思路熟悉的前提下手写出代码就更好了 为了防止不提
  • 记录-常见算法的收集

    1 快速排序 找到基准点的位置 既不浪费空间又可以快一点的排序算法 如 6 1 2 7 9 3 4 5 10 8 这10个数进行排序 首先找到一个数作为基准点 一个参照数 为了方便 让第一个数6作为基准点 然后将这个序列中所有比基准数大的数
  • 三种常用的排序方法图解及C语言实现(选择排序,冒泡排序,快速排序)

    选择排序 冒泡排序 快速排序 选择排序 选择排序是最简单直观的一种算法 选择排序是不稳定排序 基本思想 首先在未排序序列中找到最小 大 元素 存放到排序序列的起始位置 然后 再从剩余未排序元素中继续寻找最小 大 元素 然后放到已排序序列的末
  • 《数据结构》--内部排序算法比较

    题目 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶 或大概执行时间 试通过随机的数据比较各算法的关键字比较次数和关键字移动次数 以取得直观感受 基本要求 1 从以下常用的内部排序算法至少选取5种进行比较 直接插入排序 折半折
  • 快速排序(qsort)

    快速排序 排序方法有很多种 选择排序 冒泡排序 归并排序 快速排序等 看名字都知道快速排序是目前公认的一种比较好的排序算法 快速排序的核心思想是二分法 在此 我以升序为例 首先 我们需要选取一个基准数temp 再通过循环比较 将比基准数小的
  • 排序算法——比较类排序算法讲解以及c++实现

    首先我先抛一个老哥的博客 我是看着他的博客来学习理解 地址 https www cnblogs com onepixel p 7674659 html 首先说一下排序算法分为2类 一类是比较类排序算法 另一类是非比较类排序 这里主要讲常用的
  • 快速排序和归并排序的相同点和不同点(JAVA)

    首先我们贴出来快速排序的代码 public class QuickSort public int QuickSort int a int left int right int temp a left while left lt right
  • 快速排序(三种算法实现和非递归实现)

    快速排序 Quick Sort 是对冒泡排序的一种改进 基本思想是选取一个记录作为枢轴 经过一趟排序 将整段序列分为两个部分 其中一部分的值都小于枢轴 另一部分都大于枢轴 然后继续对这两部分继续进行排序 从而使整个序列达到有序 递归实现 v

随机推荐

  • np.random.normal()函数

    np random normal 的意思是一个正态分布 normal这里是正态的意思 numpy random normal loc 0 scale 1 0 size shape 参数loc float 正态分布的均值 对应着这个分布的中心
  • osg 的warning C4003: “max”宏的实参不足 error C2589: “(” : “::”右边的非法标记

    原来是需要把max用括号括起来避免和windows定义的宏混淆 std numeric limits max 或者 std max 因为Windef h中定义了 ifndef max define max a b a gt b a b en
  • Oracle中的数据类型——NUMBER

    NUMBER类型概述 NUMBER类型可以用来存储0 正数 负数 数据范围是1 10 130 1 10126 不能等于或者大于1 10126 否则Oracle会报错 算数表达式的结果同理 NUMBER类型的定义 NUMBER precisi
  • 计算机e盘丢失了,电脑E盘突然不见了怎么找回_电脑的E盘突然不见了的解决方法...

    电脑一般会有C D E F等多个磁盘 用于储存不同的程序 方便管理 近期 有用户说自己准备打开E盘安装软件 结果发现E盘突然不见了 这样就没办法把软件安装在E盘上 有什么办法能让E盘恢复 方法有的 现在整理具体操作教程给大家 具体方法如下
  • C++强制类型转换

    C 类型转换 C风格的强制转换 在C 基本的数据类型中 可以分为四类 整型 浮点型 字符型 布尔型 其中数值型包括 整型与浮点型 字符型即为char 1 将浮点型数据赋值给整型变量时 舍弃其小数部分 2 将整型数据赋值给浮点型变量时 数值不
  • 手机网站支付宝支付

    1 支付宝开放平台 支付宝手机网站支付 具体的请求参数和返回参数等相关数据 https docs open alipay com 203 107090 2 支付demo 下载手机网站支付相关的demo 这里的demo和APP支付提供的dem
  • Android webview登录手机QQ

    选择我们的应用 在对应的上述我们定义的QQActivity的onCreate或onNewIntent 如果该activity在栈里出现过 里就能响应了 通过intent取出url 找了url特征字符没有发现token或code 才发现在系统
  • 数据分析之Pandas从入门到放弃:代码+实战,9分钟带你推开Pandas大门!!!

    今天整理了一下Pandas的使用方法 应该是全网整理最完整 最简洁易读 立整 的一篇文章 嗯 别不信 确实是这样的 跟着小鱼 带你9分钟推开Pandas的大门 从此走上数据分析师的苦逼之路 Pandas使用方法 1 Pandas的基本定义
  • 制作个人图片api接口

    制作个人图片api接口 前言 准备工作 过程介绍 操作过程 上传图片到github仓库中 在github中进行项目的发布 编写php文件 引用jsDeliver上的文件 在nginx配置文件中配置好php fpm相关配置 测试 测试php配
  • MFC设计

    细说UI线程和Windows消息队列 转载于 http blog csdn net huasonl88 article details 8589396 0 tsina 1 99086 397232819ff9a47a7b7e80a40613
  • Ubuntu18.04版本安装ssh及连接ssh的常见问题

    下面我们来解决Ubuntu18 04版本安装ssh及连接ssh的常见问题 及解决方法 题外话 安装Ubuntu时会提示一句Please remove the installation medium then reboot 提示这段话 可以直
  • 以太坊网络架构解析

    以太坊网络架构解析 版权 0x7F 知道创宇404区块链安全研究团队 https www cnblogs com southx p 9334639 html 0x00 前言 区块链的火热程度一直以直线上升 其中以区块链 2 0 以太坊为代表
  • 有效服务台管理的5个关键度量指标

    从格言到ITIL 这些标准格言容易与ITSM和ITIL直接联系起来 通过ITIL实施ITSM的一个重要好处是其为持续创建 部署 实施和停役IT服务提供了一个框架 持续改进是ITIL的内在特性 它包含于ITIL服务生命周期管理的持续流程改进
  • python创建和修改yaml文件

    1 创建yaml import os import yaml desired caps train dataTrain 2007 train txt val dataTrain 2007 val txt nc 2 names a b cur
  • MFC调用mysql操作

    要用MySQL提供的C语言API 首先要包含API的头文件目录 也就是在MFC工程属性中的 包含目录 下添加MySQL安装目录的 include 文件夹 因为API是以动态链接库的形式打包的 所以还要在MFC工程属性中的 库目录 下添加My
  • pip安装python库时报Failed building wheel for xxx

    目录 一 问题描述 二 解决办法 1 下载并安装对应的 whl 文件 2 安装 whl 文件 一 问题描述 如题 在使用pip install xxx的方法安装python库 或者是基于python的软件时 报错 ERROR Failed
  • 什么是vuex?(五分钟理解vuex)

    1 什么是vuex 官方的理解是 Vuex 是一个专为 Vue js 应用程序开发的状态管理模式 它采用集中式存储管理应用的所有组件的状态 并以相应的规则保证状态以一种可预测的方式发生变化 Vuex 也集成到 Vue 的官方调试工具 dev
  • 10kV 电压互感器TV高压熔断器熔断可能是什么原因?

    10kV 电压互感器TV高压熔断器熔断可能是什么原因 答 1 当系统在某种运行方式 某种条件下 可能产生铁磁共振 这时也会产生过电压 有可能使TV的激磁电流增加十儿倍 会引起高压侧熔断器熔断 2 系统发生单相间谐电弧接地时 会出现过电压 可
  • 从数组中找出最小的k个数

    调整堆 小顶堆 void HeapAdjust int A int parent int length temp保存当前父节点parent int temp A parent 左子结点开始 i节点的左孩子为2i 1 右孩子为2i 2 for
  • Python实现快速排序

    Python实现快速排序 一 快速排序简介 快速排序 Quick Sort 是一种效率很高的排序算法 是对冒泡排序的一种改进排序算法 快速排序首先任意选取一个数据 通常选待排序列表中的第一个数 作为基准数据 将待排序列表中的数据分割成独立的