【Algorithms 4】算法(第4版)学习笔记 05 - 2.2 归并排序

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:归并排序的简单演示
      • 1.1:基本思路
      • 1.2:归并排序的 demo 演示
      • 1.3:代码实现
      • 2:自顶向下的归并排序
      • 2.1:比较次数与访问次数的证明
      • 2.2:代码优化
      • 2.3:优化后代码实现
      • 3:自底向上的归并排序
      • 3.1:代码实现
      • 4:排序算法的复杂度
      • 5:稳定性
      • 5.1:插入排序:稳定
      • 5.2:选择排序:不稳定
      • 5.3:希尔排序:不稳定
      • 5.4:归并排序:稳定

前言

本章节主要内容是 归并排序,除此之外还有 排序算法的复杂度 以及 稳定性 的相关内容。

本章节中间有穿插说明 比较器(Compartor),不过本文暂且略过这一内容,感兴趣的朋友建议移步视频自行学习总结。

参考目录

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

学习笔记

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

1:归并排序的简单演示

1.1:基本思路

归并排序基本思路:

  • 数组一分为二
  • 每一半 递归 排序
  • 合并两半

在这里插入图片描述

1.2:归并排序的 demo 演示

对于归并排序,Sedgewick 教授的视频进行了分步演示,下面截图进行简单说明。

排好序的两个子数组:

在这里插入图片描述

在原数组的基础上复制一个辅助数组:

在这里插入图片描述

需要三个下标来进行操作:
i、j分别是两个比较的子数组的下标,k是原数组的下标。

比较两个子数组的数据,将较小的值放回原数组:

在这里插入图片描述

如果两个值相同,则将左侧子数组的值放回原数组:

在这里插入图片描述

如果其中一个子数组已经没有元素,则另一个子数组的元素直接放回原数组:

在这里插入图片描述

1.3:代码实现

edu.princeton.cs.algs4.Merge#merge

在这里插入图片描述

edu.princeton.cs.algs4.Merge#sort

在这里插入图片描述

2:自顶向下的归并排序

上面分步实现的归并排序是属于自顶向下的归并排序。官网给出了归并的分步结果图:

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

2.1:比较次数与访问次数的证明

比较次数和访问次数是衡量一个算法优劣与否的重要参考标准,因此这里给出了相关的证明。

(截图自视频 PPT)
在这里插入图片描述

每次归并最多需要访问数组6N次:

  • 2N次用来复制
  • 2N次用来将排好序的元素移动回去
  • 另外最多比较2N次

视频中,教授使用长度 N 为 2n 的数组来证明:
D ( N ) = 2 D ( N / 2 ) + N , N > 1 ,且 D ( 1 ) = 0 D(N) = 2D(N/2) + N,N>1,且 D(1) = 0 D(N)=2D(N/2)+NN>1,且D(1)=0

一共有三种证明方式,但说实话我看了几遍还是没太懂怎么算的(哭),先把证明方式贴出来:

方式一:图形法证明

在这里插入图片描述

方式二:数学方式证明

在这里插入图片描述

方式三:数学归纳法证明

在这里插入图片描述

这里再贴一下书里面的相关证明帮助理解:

在这里插入图片描述

命题F。对于长度为N的任意数组,自顶向下的归并排序需要½NlgN至NlgN次比较。

书中关于命题 F 的证明,相对来说容易理解一些,可以自行参考学习。

2.2:代码优化

归并排序虽然速度比较快,但是也有一些缺点,因此也提出了一些优化方案:(这里列出对应的章节)

  • 2.2.2.1 对小规模子数组使用插入排序
  • 2.2.2.2 测试数组是否已经有序
  • 2.2.2.3 不将元素复制到辅助数组

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3:优化后代码实现

edu.princeton.cs.algs4.MergeX#sort

在这里插入图片描述

3:自底向上的归并排序

自顶向下的归并排序使用了递归的方式,为了减少递归的操作,又提出了自底向上的归并排序。

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

3.1:代码实现

edu.princeton.cs.algs4.MergeBU#sort

在这里插入图片描述

4:排序算法的复杂度

这里使用了决策树来进行说明,不过我觉得这一部分书本的说明不是很好,有些地方说得云里雾里的……

例如:

在这里插入图片描述

一眼看过去不知道是啥。然后看教授的PPT:

在这里插入图片描述

还有对于命题 I 的描述,每一个字我都认识,愣是读了好几遍才读通顺:

命题I。没有任何基于比较的算法能够保证使用少于lg(N!)~NlgN次比较将长度为N的数组排序。

再来看看视频里是怎么说的:

Any compare-based sorting algorithm must use at least lg(N!)~NlgN compares in the worst-case.
任何基于比较的排序算法,在最坏的情况下需要使用 lg(N!)~NlgN 次比较。

贴一下完整的 PPT 截图,一目了然:

在这里插入图片描述

证明:

  • 假设数组由N个不同的值 a1 到 aN 组成。
  • 最坏的情况由决策树的 高度 h 决定。
  • 高度为 h 的二叉树最多有 2h 叶子节点。
  • N! 不同的排序 => 至少 N! 叶子节点。

根据书里面的说明再完善一下:

从比较树观察得到的第一个重要结论是这棵树应该至少有 N! 个叶子结点,因为 N 个不同的主键会有 N! 种不同的排列。


二叉树的一个基本的组合学性质就是高度为 h 的树最多只可能有 2h 个叶子结点,拥有 2h 个结点的树是完美平衡的,或称为完全树。

在这里插入图片描述

5:稳定性

这一部分回顾了目前所讲到的四种算法:插入排序、选择排序、希尔排序以及归并排序。

Q:哪些算法是稳定的?
A:插入排序和归并排序。(选择排序和希尔排序不稳定。)

5.1:插入排序:稳定

在这里插入图片描述

插入排序中,相同的值不会越过彼此。

通常而言,看一个排序是否稳定,一般是看它是否有长距离的交换可能使得一条记录越过某一条相同值的记录。

5.2:选择排序:不稳定

在这里插入图片描述

5.3:希尔排序:不稳定

在这里插入图片描述

5.4:归并排序:稳定

只要归并操作是稳定的,那么归并排序算法就是稳定的;操作是否稳定,取决于代码怎么写。

在这里插入图片描述

(完)

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

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

相关文章

Rhino.Inside带材质将Revit模型bake到Rhino

Hello大家好!我是九哥~ 今天来讲一个小技巧,就是我通常采用RIR将Revit的模型的Geometry Bake到Rhino,肯定是没有材质的,那么如果我们需要带材质那要怎么办呢? 对于会的人,其实挺简单的,只需要…

Retinexformer论文精读笔记

Retinexformer论文精读笔记 论文为2023年ICCV的Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement。论文链接:browse.arxiv.org/pdf/2303.06705.pdf,代码链接:caiyuanhao1998/Retinexformer: “Retinexfo…

vscode预览github上的markdown效果

需要安装的插件有: Github Markdown Preview Markdown Checkboxes Markdown Emoji Markdown footnotes Markdown Preview Github Styling Markdown Preview Mermaid Support Markdown yaml Preamble ctrlshiftv结合双页功能

4、ChatGPT 无法完成的 5 项编码任务

ChatGPT 无法完成的 5 项编码任务 这是 ChatGPT 不能做的事情的一个清单,但这并非详尽无遗。ChatGPT 可以从头开始生成相当不错的代码,但是它不能取代你的工作。 我喜欢将 ChatGPT 视为 StackOverflow 的更智能版本。非常有帮助,但不会很快取代专业人士。当 ChatGPT 问世时…

万物皆可问 — 私有部署网易有道QAnything

什么是 QAnything? QAnything(Question and Answer based on Anything)是一个本地知识库问答系统,旨在支持多种文件格式和数据库,允许离线安装和使用。使用QAnything,您可以简单地删除本地存储的任何格式的…

WifiConfigStore初始化读取-Android13

WifiConfigStore初始化读取 1、StoreData创建并注册2、WifiConfigStore读取2.1 文件读取流程2.2 时序图2.3 日志 1、StoreData创建并注册 packages/modules/Wifi/service/java/com/android/server/wifi/WifiConfigManager.java mWifiConfigStore.registerStoreData(mNetworkL…

利用LLM大模型生成sql的深入应用探究

Chat2DB 是一款有开源免费的多数据库客户端工具,和传统的数据库客户端软件Navicat、DBeaver 相比 Chat2DB 集成了 AIGC 的能力,能够将自然语言转换为 SQL,也可以将 SQL 转换为自然语言,可以给出研发人员 SQL 的优化建议,极大地提升…

流量嗅探详解

不少人存在这样的观点:只要计算机安装各种专业的安全软件,系统及时更 新补丁,密码尽可能复杂,那么计算机就会避免遭到入侵。当然这样的确不容易 被入侵,但那也只是针对传统的病毒、木马而言,在流量攻击面前…

Qt 常见容器类用法(一)

目录 QMap类 QHash类 QVector类 QMap类 QMap<key,T>提供一个从类型为Key的键到类型为T的值的映射。通常&#xff0c;QMap存储的数据形式是一个键对应一个值&#xff0c;并且按照键Key的次序存储数据。为了能够支持一键多值的情况&#xff0c;QMap提供QMap<key,T&g…

C语言——字符、数组和函数指针变量

目录 1. 字符指针变量2. 数组指针变量2.1 数组指针变量是什么&#xff1f;2.2 数组指针变量怎么初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 typedef关键字 5. 函数指针数组6. 转移表 1. 字符指针变量 在指针的类型中我们知道…

解析基于检索排序的知识图谱问答系统

目录 前言1 问句的表示与语义理解1.1 问句表示的重要性1.2 端到端网络的优势 2 知识图谱中的排序问题2.1 知识图谱的核心作用2.2 查询匹配的转化与排序问题2.3 实体链接的关键性2.4 路径的构建与系统优化 3 难点与挑战3.1 实体链接、命名实体识别和消歧3.2 排序模型的挑战 4 优…

泛娱乐社交出海洞察,Flat Ads解锁海外增长新思路

摘要:解读泛娱乐社交应用出海现状与趋势,解锁“掘金”泛娱乐社交出海赛道新思路。 根据全球舆情监测机构 Meltwater 和社交媒体机构We are Social最新发布数据显示,全球社交媒体活跃用户数量已突破50亿,约占世界人口总数62.5%。庞大的用户数量意味着广阔的增量空间,目前,随着全…