【Algorithms 4】算法(第4版)学习笔记 06 - 2.3 快速排序

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:基本算法
      • 1.1:快速排序 demo 演示
      • 1.2:快速排序切分代码实现
      • 1.3:实现细节
      • 1.4:案例分析
      • 1.4.1:最佳案例
      • 1.4.2:最坏案例
      • 1.4.3:平均案例分析
      • 1.5:特征总结
      • 1.6:算法优化
      • 2:Dijkstra 三向切分的快速排序
      • 2.1:三向切分 demo 演示
      • 2.2:三向切分代码实现
      • 2.3:熵最优
      • 3:排序算法小总结

前言

本章节主要内容是 快速排序。快速排序被誉为二十世纪十大算法之一,至今也十分常用。

本文的主要内容包括 快速排序 以及 三向切分快速排序,视频课程中还有关于快速选择(quick selection)以及计算机系统应用的一些说明,本文不详细展开,感兴趣的朋友建议移步视频自行学习总结。

参考目录

  • B站 普林斯顿大学《Algorithms》视频课
    (请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。)
  • 微信读书《算法(第4版)》
    (本文主要内容来自《2.3 快速排序》)
  • 官方网站
    (有书本配套的内容以及代码)

学习笔记

注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。

1:基本算法

快速排序的递归是在它完成工作之后,而归并排序是在它完成工作之前。

基本过程:

  • 数组随机洗牌
  • 用一些 j 分割数组:
    • a[j] 在数组中
    • j 左边都是比它小的数
    • j 右边都是比它大的数

(对每一部分进行递归排序)

(截图自官网)
在这里插入图片描述

1.1:快速排序 demo 演示

在这里插入图片描述

阶段一:重复扫描直到指针 i 和 j 交叉。

  • i 指针从左到右扫描,只要 a[i] < a[lo]
  • j 指针从右到左扫描,只要 a[j] > a[lo]
  • 交换 a[i] 和 a[j]

阶段二:当指针i和j交叉后

  • 交换 a[lo] 和 a[j]

在这里插入图片描述

阶段二之后实际上就分区结束了。

(截图自官网)
在这里插入图片描述

切分轨迹:

(截图自官网)
在这里插入图片描述

1.2:快速排序切分代码实现

edu.princeton.cs.algs4.Quick#partition

在这里插入图片描述

edu.princeton.cs.algs4.Quick#sort

在这里插入图片描述

1.3:实现细节

(这里列出对应的章节)

  • 2.3.1.1 原地切分
  • 2.3.1.2 别越界
  • 2.3.1.3 保持随机性
  • 2.3.1.4 终止循环
  • 2.3.1.5 处理切分元素值有重复的情况
  • 2.3.1.6 终止递归

官网上也作了简单的说明:

(截图自官网)
在这里插入图片描述

1.4:案例分析

1.4.1:最佳案例

在这里插入图片描述

1.4.2:最坏案例

在这里插入图片描述

1.4.3:平均案例分析

这一环节,教授对于快速排序的分析作了数学模型的证明,对应了书本的命题 K。

命题K。将长度为N的无重复数组排序,快速排序平均需要~2NlnN次比较(以及1/6的交换)。

书本和教授视频里面都给出了相关的证明过程,不过说实话数学不好真的有点伤脑筋,我花了一点时间去搞懂证明过程。

先列举一下教授视频里面的证明过程:

在这里插入图片描述


在这里插入图片描述

特别是最后两步的近似过程,一开始一脸懵逼……

然后后面多亏了在线计算器,大致证明过程如下(iPad 写得比较丑,凑合看):

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

其中:
在这里插入图片描述

(https://mathdf.com/int/cn/)

在这里插入图片描述

(https://www.lddgo.net/math/logarithm-calculator)

1.5:特征总结

在这里插入图片描述

简单翻译一下:

最坏的情况:比较次数是平方级别
(不过你的电脑被闪电击中的可能性更大,可以参见命题L证明)

一般情况:比较数为 ~ 1.39NlgN

  • 比较次数比归并排序多39%
  • 但是实际上比归并排序更快,因为数据移动少

随机洗牌:

  • 最坏情况下的概率保证
  • 基本数学模型可以通过实验验证

需要注意。实际上很多教科书上的实现是平方级别的,假如数组:

  • 进行排序或反向排序
  • 有许多重复项(即使是随机的!)

在这里插入图片描述

快速排序是原地排序算法。

  • 切分:恒定的额外空间
  • 递归深度:对数额外空间(大概率)
    (可以通过在较小的子数组上递归到较大的子数组来保证对数深度)

快速排序是不稳定的。

1.6:算法优化

  • 2.3.3.1 切换到插入排序
  • 2.3.3.2 三取样切分
  • 2.3.3.3 熵最优的排序

在这里插入图片描述


在这里插入图片描述

2:Dijkstra 三向切分的快速排序

前面总结有提及到:如果有很多重复项的时候,快速排序会很慢。因而有了三向切分的优化方式。

(截图自官网)
在这里插入图片描述

在这里插入图片描述

2.1:三向切分 demo 演示

初始数组:

在这里插入图片描述

情况一:a[i] < v

在这里插入图片描述

情况二:a[i] > v

在这里插入图片描述

情况三:a[i] = v

在这里插入图片描述

分割完成:

在这里插入图片描述

切分轨迹:

(截图自官网)
在这里插入图片描述

2.2:三向切分代码实现

教授:amazingly simple

edu.princeton.cs.algs4.Quick3way#sort

在这里插入图片描述

2.3:熵最优

在这里插入图片描述
(熵最优的证明超出了课程范围)

3:排序算法小总结

对于前面的六种算法作了简单总结:

在这里插入图片描述

做成表格简单翻译一下:

原地?稳定?最坏平均最好备注
选择排序N2/2N2/2N2/2N次交换
插入排序N2/2N2/4NN较小或者是部分排序时使用
希尔排序??N编码紧凑,次平方时间复杂度
次平方:指其运行时间的增长速度低于问题规模(通常是输入大小)的平方
归并排序NlgNNlgNNlgNNlogN保证,稳定
快速排序N2/22NlnNNlgNNlogN概率保证,在实践中最快
三向切分快速排序N2/22NlnNN改进存在重复键时的快排
???NlgNNlgNNlgN排序的圣杯
在计算机编程中,“Holy Sorting Grail”这个表达通常用来比喻一种理想化的排序算法。

(完)

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

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

相关文章

【MySQL】学习和总结DCL的权限控制

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Bl9kYeLf8GfpdQgL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

消息队列MQ 介绍

&#x1f47d;System.out.println(“&#x1f44b;&#x1f3fc;嗨&#xff0c;大家好&#xff0c;我是代码不会敲的小符&#xff0c;双非大四&#xff0c;Java实习中…”); &#x1f4da;System.out.println(“&#x1f388;如果文章中有错误的地方&#xff0c;恳请大家指正&a…

Vue-56、Vue技术路由的使用

路由 1、理解&#xff1a;一个路由&#xff08;route&#xff09;就是一种映射关系&#xff08;key-value&#xff09;&#xff0c;多个路由需要路由器&#xff08;router&#xff09;进行管理。 2、前端路由&#xff1a;key是路径&#xff0c;value是组件 1、基本使用 vue…

JFinal中如何实现反序列化----JSON字符串向Model对象转换

需求: 将客户端传来的requestbody反序列化成对应的Model对象。 一、反序列化--驼峰命名 1、fastjson实现 JFinal中没有提供反序列化的方法&#xff0c;因为大多数情况下&#xff0c;可以直接通过jar包进行转换&#xff0c;如利用fastjson&#xff0c;我们可以通过如下方式进行…

Renitialized existing Git repositoy in D:/libai/project/gitab-cicd-test/.git/

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

vue 引入 百度地图API 和 路书

公司项目中&#xff0c;偶尔都会涉及到地图的使用&#xff0c;这里以百度地图为例&#xff0c;我们梳理一下引用流程及注意点 账号和获取密钥 百度地图示例 百度地图 类参考 1、账号和获取密钥 // api.map.baidu.com/api?typewebgl&v3.0&ak您的密钥<script type…

1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 关于这部分&#xff0c;从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实&#xff0c;RTOS存在的一个主要的目…

机器学习系列——(十七)聚类

引言 在当今数据驱动的时代&#xff0c;机器学习已经成为了解锁数据潜能的关键技术之一。其中&#xff0c;聚类作为机器学习领域的一个重要分支&#xff0c;广泛应用于数据挖掘、模式识别、图像分析等多个领域。本文旨在深入探讨聚类技术的原理、类型及其应用&#xff0c;为读…

【Flink入门修炼】1-3 Flink WordCount 入门实现

本篇文章将带大家运行 Flink 最简单的程序 WordCount。先实践后理论&#xff0c;对其基本输入输出、编程代码有初步了解&#xff0c;后续篇章再对 Flink 的各种概念和架构进行介绍。 下面将从创建项目开始&#xff0c;介绍如何创建出一个 Flink 项目&#xff1b;然后从 DataStr…

IDEA创建Java类时自动添加注释(作者、年份、月份)

目录 IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;如图&#xff1a; IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09; 简单记录下&#xff0c;IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;&#…

Java+微信小程序实现智慧家政系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…

【SparkML实践7】特征选择器FeatureSelector

本节介绍了用于处理特征的算法&#xff0c;大致可以分为以下几组&#xff1a; 提取&#xff08;Extraction&#xff09;&#xff1a;从“原始”数据中提取特征。转换&#xff08;Transformation&#xff09;&#xff1a;缩放、转换或修改特征。选择&#xff08;Selection&…

作业2.8

1、选择题 1.1、以下选项中,不能作为合法常量的是 ____B______ A&#xff09;1.234e04 B&#xff09;1.234e0.4 C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____D________。 A) char c1 ‘H’ &#xff1b; B) char c…

RabbitMQ高可用架构涉及常用功能整理

RabbitMQ高可用架构涉及常用功能整理 1. rabbitmq的集群模式2. 镜像模式高可用系统架构和相关组件3. rabbitmq的核心参数3.1 镜像策略3.2 新镜像同步策略3.3 从节点晋升策略3.4 主队列选择策略 4. rabbitmq常用命令4.1 常用基础命令4.1.1 服务管理4.1.2 用户管理4.1.3 角色管理…

数字图像处理(实践篇)四十七 OpenCV-Python 高动态范围HDR

目录 一 HDR 二 实践 高质量的图像具备的要素如下: ①分辨率 图像中的像素数量。在特定屏幕尺寸下,分辨率越高,像素越多,显示的细节更精细。 ②位深度

JavaEE作业-实验三

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 简单的线上图书交易系统的web层 2 实验要求 ①采用SpringMVC框架&#xff0c;采用REST风格 ②要求具有如下功能&#xff1a;商品分类、订单、购物车、库存 ③独立完成&#xff0c;编写实验报告 …

OOP设计模式与JAVA之间存在怎么样的关系?

面向对象程序设计&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09;是一种程序设计范型&#xff0c;它以对象为基础&#xff0c;将数据和操作封装在一起&#xff0c;形成一个独立的实体。OOP设计模式是面向对象程序设计的一种应用&#xff0c;它提供了一种在…

自然语言处理(NLP)——使用Rasa创建聊天机器人

1 基本概念 1.1 自然语言处理的分类 IR-BOT&#xff1a;检索型问答系统 Task-bot&#xff1a;任务型对话系统 Chitchat-bot:闲聊系统 1.2 任务型对话Task-Bot:task-oriented bot 这张图展示了一个语音对话系统&#xff08;或聊天机器人&#xff09;的基本组成部分和它们之间的…

外贸邮件群发如何做?外贸邮件群发靠谱吗?

外贸邮件群发有哪些平台&#xff1f;外贸群发邮件用什么邮箱&#xff1f; 外贸邮件群发是许多企业在开展国际贸易时常用的营销手段&#xff0c;它不仅能够快速地将产品信息和促销活动传达给目标客户&#xff0c;还能够有效地建立和维护客户关系。下面&#xff0c;就让蜂邮探讨…

【JavaScript】switch 语句

文章目录 1. 基础的 switch 语句2. 多个条件的处理3. 使用 switch 进行条件判断4. switch 语句 vs if-else 语句5. 总结 在 JavaScript 中&#xff0c; switch 语句是一种 用于根据不同的条件值执行不同代码块的控制流结构。本篇博客将介绍 JavaScript 中的 switch 语句&…