【Algorithms 4】算法(第4版)学习笔记 07 - 2.4 优先队列

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:API
      • 1.1:实现 demo 示例
      • 1.2:初级实现(有序或无序的数组)
      • 2:二叉堆
      • 2.1:完全二叉树
      • 2.2:二叉堆
      • 2.2.1:堆的表示
      • 2.2.2:属性
      • 2.3:堆算法:由下至上的堆有序化(上浮)
      • 2.3.1:swim 介绍
      • 2.3.2:swim 代码实现
      • 2.3.3:应用:堆插入节点
      • 2.3.4:swim 应用代码实现
      • 2.3.5:swim 应用 demo 演示
      • 2.4:堆算法:由上至下的堆有序化(下沉)
      • 2.4.1:sink 介绍
      • 2.4.2:sink 代码实现
      • 2.4.3:应用:堆删除最大节点
      • 2.4.4:sink 应用代码实现
      • 2.4.5:sink 应用 demo 演示
      • 2.5:优先队列实现开销小结
      • 2.6:实际考虑
      • 3:堆排序
      • 3.1:堆排序 demo 演示
      • 3.1.1:堆构造阶段
      • 3.1.2:堆排序阶段(下沉排序)
      • 3.2:代码实现
      • 3.3:堆排序数学分析
      • 4:排序算法小结

前言

本文的主要内容包括 二叉堆 以及 堆排序,视频课程中还有关于事件驱动模拟(event-driven simulation)的介绍,本文不详细展开,感兴趣的朋友建议移步视频自行学习总结。

参考目录

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

学习笔记

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

1:API

表2.4.1 泛型优先队列的API
在这里插入图片描述

1.1:实现 demo 示例

为了展示优先队列的抽象模型的价值,考虑以下问题:输入N个字符串,每个字符串都对应着一个整数,你的任务就是从中找出最大的(或是最小的)M个整数(及其关联的字符串)。

edu.princeton.cs.algs4.TopM

在这里插入图片描述

1.2:初级实现(有序或无序的数组)

UnorderedArrayMaxPQ

源码里面没有这个类,给出官网的 传送门。

Sedgewick 教授的评价:

(这是一个)“作弊”的版本:该方式要求用户提供数组初始空间。

OrderedArrayMaxPQ

源码里面没有这个类,给出官网的 传送门。

表2.4.3 优先队列的各种实现在最坏情况下运行时间的增长数量级
在这里插入图片描述
(注:堆在后文详细说明)

2:二叉堆

2.1:完全二叉树

二叉堆的概念基于完全二叉树。

在这里插入图片描述

来简单汉化一下:

Binary tree.Empty or node with links to left and right binary trees.

二叉树。要么为空,要么为一个带有指向左右子二叉树链接的节点。

Complete tree.Perfectly balanced,except for bottom level.

完全树(Complete Tree)。除了最底层外,完美平衡。

进一步理解一下:

  • 二叉树是一种数据结构,它或者是空的,或者是包含一个节点,该节点有两个指针分别链接到它的左子二叉树和右子二叉树。
  • 完全二叉树是一种特殊的二叉树,其特点是除了最后一层外,所有层都是完全填满的,即所有节点都有两个子节点,除非它们是位于最后一层的叶子节点。这意味着完全二叉树非常接近平衡状态,仅在最底层可能出现节点数量不均等的情况。

Property.Height of complete tree with N nodes is [lg N].

性质:具有 N 个节点的完全二叉树的高度是 [lg N]。

Pf.Height only increases when N is a power of 2.

证明:高度仅在 N 是 2 的幂时增加。

这里的证明有点随意……我个人感觉这个证明有点类似 1.5 章节中的 加权 quick-union 方法中的证明,可以回头看下。

2.2:二叉堆

本节中的二叉堆都是以 max-heap 进行说明,与之相对应的是 min-heap。

这两者的区别可以看下这个图:

图源:Hello 算法
https://www.hello-algo.com/chapter_heap/heap/
在这里插入图片描述

2.2.1:堆的表示

在这里插入图片描述

来简单汉化一下:

Binary heap.Array representation of a heap-ordered complete binary tree.

二叉堆。一种使用数组表示的堆排序完全二叉树。

Heap-ordered binary tree.

  • Keys in nodes.
  • Parent’s key no smaller than children’s keys.

堆序二叉树。

  • 节点中包含键(关键字)。
  • 父节点的键不小于其子节点的键。

Array representation.

  • Indices start at 1.
  • Take nodes in level order.
  • No explicit links needed!

数组表示。

  • 索引从1开始计数。
  • 按层级顺序遍历节点。
  • 无需显式链接!

进一步说明:

  • 索引从1开始计数:这里的“索引从1开始”是指数组的第一个元素对应于二叉树中的根节点,而非通常编程语言中数组索引从0开始的习惯。
  • 按层级顺序遍历节点:这意味着我们可以按照二叉树的层级顺序(也称为广度优先搜索顺序)依次访问数组中的元素,从而实现对整个二叉树的遍历。
  • 无需显式链接:由于采用数组存储并利用了完全二叉树的特点,可以通过计算得出任意节点的父节点或子节点在数组中的位置,因此不需要像传统链表那样为每个节点设置显式的指针来指向其父节点或子节点。

2.2.2:属性

没有截图教授的 PPT 内容,不过还是将关键的内容汉化一下。

Proposition.Largest key is a[1],which is root of binary tree.

最大的键是a[1],这是二叉树的根节点。

Proposition.Can use array indices to move through tree.

  • Parent of node at k is at k/2.
  • Children of node at k are at 2k and 2k+1.

命题:可以使用数组索引遍历二叉树节点。

  • 索引为 k 的节点的父节点位于索引 k/2 处(整数除法)。
  • 索引为 k 的节点的子节点分别位于索引 2k 和 2k+1 处。

进一步解释:

这个命题描述了如何通过数组来实现堆序完全二叉树的逻辑结构。当完全二叉树采用数组表示时,可以通过简单的算术运算快速定位任意节点的父节点和子节点:

  • 要访问某个节点 k 的父节点,只需将索引 k 除以 2(通常采用向下取整的整数除法),得到的结果就是其父节点在数组中的位置。
  • 对于索引为 k 的节点,其左孩子节点的位置是索引 2k,右孩子节点的位置是索引 2k+1。

这种数组表示方法省去了显式维护指针链接的需要,极大地简化了算法实现,并提高了存储和操作效率。

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

2.3:堆算法:由下至上的堆有序化(上浮)

2.3.1:swim 介绍

场景:子节点比父节点大。

消除违例:

  • 交换异常的父子节点。
  • 重复此操作,直到恢复堆顺序。

在这里插入图片描述

2.3.2:swim 代码实现

edu.princeton.cs.algs4.MaxPQ#swim

在这里插入图片描述

2.3.3:应用:堆插入节点

插入节点:在末尾加入元素,然后让其swim到相应的位置。

开销:最多 1 + lgN 次交换。

在这里插入图片描述

2.3.4:swim 应用代码实现

edu.princeton.cs.algs4.MaxPQ#insert

在这里插入图片描述

2.3.5:swim 应用 demo 演示

初始状态:

在这里插入图片描述

将新的节点加入到数组末尾(打破了堆顺序,swim):

在这里插入图片描述

与父级进行交换,直到顺序正确。

第一次交换:

在这里插入图片描述

第二次交换:

在这里插入图片描述

S比T小,交换结束。

最终堆有序状态:

在这里插入图片描述

2.4:堆算法:由上至下的堆有序化(下沉)

2.4.1:sink 介绍

场景:父节点比它的两个子结点或是其中之一更小。

消除违例:

  • 将父节点与较大的子节点进行交换。
  • 重复此操作,直到恢复堆顺序。

在这里插入图片描述
图2.4.4 由上至下的堆有序化(下沉)

2.4.2:sink 代码实现

edu.princeton.cs.algs4.MaxPQ#sink

在这里插入图片描述

2.4.3:应用:堆删除最大节点

删除最大节点:交换根节点与末尾的元素,然后让新的根节点sink到相应的位置。

开销:最多 2lgN 次交换。

在这里插入图片描述

2.4.4:sink 应用代码实现

edu.princeton.cs.algs4.MaxPQ#delMax

在这里插入图片描述

2.4.5:sink 应用 demo 演示

初始状态:

在这里插入图片描述

与末尾的节点交换:

在这里插入图片描述

删除末尾的元素,并得到新的根节点(打破了堆顺序,sink):

在这里插入图片描述

与较大的子节点进行交换,直到顺序正确。

第一次交换:

在这里插入图片描述

第二次交换:

在这里插入图片描述

H比G大,交换结束。

最终堆有序状态:

在这里插入图片描述

2.5:优先队列实现开销小结

在这里插入图片描述

2.6:实际考虑

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

3:堆排序

3.1:堆排序 demo 演示

3.1.1:堆构造阶段

在这里插入图片描述

堆的构造。使用自底向上的方法构建大顶堆。(假设数组元素下标是1到N)

初始状态:任意排序的数组

在这里插入图片描述

第一步:单节点堆

开始时我们只需要扫描数组中的一半元素,因为我们可以跳过大小为1的子堆。

在这里插入图片描述

第二步:3节点堆(数组从右往左扫描)

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

依次扫描E(5)、T(4)、R(3):

在这里插入图片描述

第三步:7节点堆

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

7节点堆下沉完成。

第四步:11节点堆(完全二叉树:15节点堆)

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

11节点堆下沉完成。

堆构造阶段结束。

3.1.2:堆排序阶段(下沉排序)

在这里插入图片描述

下沉排序(降序排序)。重复删除数组中最大的剩余元素项。

即持续交换下标1与末尾的元素,并使用 sink 方法重新排序。参考前文 2.4.5 demo。

最终得到的结果:

在这里插入图片描述

3.2:代码实现

edu.princeton.cs.algs4.Heap#sort

在这里插入图片描述

在这里插入图片描述
图2.4.7 堆排序:堆的构造(左)和下沉排序(右)

3.3:堆排序数学分析

在这里插入图片描述

汉化:

定理:构建一个堆需要 <= 2N 次比较和交换操作。
定理:堆排序需要 <= 2NlgN 次比较和交换操作。

重要性。最坏情况为NlogN的原地排序算法。

  • 归并排序:no,线性额外空间。(可以原地合并,但不实用)
  • 快速排序:no,最坏情况是平方时间。(可能最坏情况是NlogN,但不实用)
  • 堆排序:yes!

底线。堆排序在时间和空间上都是最优的。但是:

  • 内层循环时间比快速排序长
  • 缓存使用不充分(使用率低)
  • 不稳定

4:排序算法小结

在这里插入图片描述

做成表格简单汉化一下:

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

(完)

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

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

相关文章

Java 基于 SpringBoot+Vue 的智慧外贸平台的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【Vue】Vue基础入门

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue ⛺️稳重求进&#xff0c;晒太阳 Vue概念 是一个用于构建用户界面的渐进式框架优点&#xff1a;大大提高开发效率缺点&#xff1a;需要理解记忆规则 创建Vue实例 步骤&#xff1a; …

Arm发布新的人工智能Cortex-M处理器

Arm发布了一款新的Cortex-M处理器&#xff0c;旨在为资源受限的物联网&#xff08;IoT&#xff09;设备提供先进的人工智能功能。这款新的Cortex-M52声称是最小的、面积和成本效率最高的处理器&#xff0c;采用了Arm Helium技术&#xff0c;使开发者能够在单一工具链上使用简化…

小结与数字的魅力的开篇

小结 本系列主要介绍了一些排序算法&#xff0c;包括冒泡排序、快速排序、直接插入排序、希尔排序、简单选择排序、堆排序、归并排序、计数排序、桶排序和基数排序。 排序算法本身并不难&#xff0c;但其涉及的知识点却星罗棋布&#xff0c;其变化莫测的思路更让人难以捉摸&am…

移动机器人激光SLAM导航(五):Cartographer SLAM 篇

参考 Cartographer 官方文档Cartographer 从入门到精通 1. Cartographer 安装 1.1 前置条件 推荐在刚装好的 Ubuntu 16.04 或 Ubuntu 18.04 上进行编译ROS 安装&#xff1a;ROS学习1&#xff1a;ROS概述与环境搭建 1.2 依赖库安装 资源下载完解压并执行以下指令 https://pa…

Spring Boot 笔记 009 创建接口_更新用户基本信息

1.1.1 给User实体类添加校验 package com.geji.pojo;import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta…

【Java程序设计】【C00260】基于Springboot的企业客户信息反馈平台(有论文)

基于Springboot的企业客户信息反馈平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的企业客户信息反馈平台 本系统分为平台功能模块、管理员功能模块以及客户功能模块。 平台功能模块&#xff1a;在平台首页可…

FastAI 之书(面向程序员的 FastAI)(六)

原文&#xff1a;www.bookstack.cn/read/th-fastai-book 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十三章&#xff1a;卷积神经网络 原文&#xff1a;www.bookstack.cn/read/th-fastai-book/44d8848dfac0c1b0.md 译者&#xff1a;飞龙 协议&#xff1a;CC BY-N…

【Java程序设计】【C00257】基于Springboot的校园二手书交易平台(有论文)

基于Springboot的校园二手书交易平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的乐校园二手书交易管理系统 本系统分为系统功能模块、管理员功能模块、卖家用户功能模块以及用户功能模块。 系统功能模块&…

【教程】C++语言基础学习笔记(九)——指针

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

消息中间件特点

1.  消息中间件概念 消息中间件是消息传递的过程中保存消息的容器。 主要目的&#xff1a;提供路由并保证消息的传递&#xff1b;如果发送消息时接受者不可用&#xff0c;消息队列会保留信息&#xff0c;直到可以成功传递为止。 消息中间件保存消息也是有期限的。 2.  消息…

车载软件架构 —— Adaptive AUTOSAR软件架构

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师&#xff08;Wechat&#xff1a;gongkenan2013&#xff09;。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 本就是小人物&#xff0c;输了就是输了&#…

【Zigbee课程设计系列文章】Zigbee开发环境搭建

【Zigbee课程设计系列文章】Zigbee开发环境搭建 前言IAR 下载安装Z-Stack协议栈安装 &#x1f38a;项目专栏&#xff1a;【Zigbee课程设计系列文章】&#xff08;附详细使用教程完整代码原理图完整课设报告&#xff09; 前言 &#x1f451;由于无线传感器网络&#xff08;也即…

每日一练——月落乌啼算钱

题目&#xff1a; 举例&#xff1a; 输入&#xff1a;6&#xff0c;输出&#xff1a;8.00 最开始看到这道题还有点蒙&#xff0c;但是看到他的公式想起了斐波那契数列 1,1,2,3,5,8...... 由前两个数相加得到第三个数&#xff0c;为An2An1An。 可以得出这个题目中所给的通项就…

大更新!gpt加入记忆功能,可以记忆自己的提问啦!

2月14日凌晨&#xff0c;OpenAI在官网宣布&#xff0c;正在测试ChatGPT记住用户提问内容的能力&#xff0c;同时可以自由控制其内存。 该功能使用户不必频繁地提问相同的内容&#xff0c;ChatGPT都将记住那些内容并对长对话、个性化聊天等&#xff0c;例如&#xff0c;写长文小…

基于Python的HTTP隧道安全性分析:魔法背后的锁与钥匙

当我们谈论基于Python的HTTP隧道时&#xff0c;不禁让人想起那些神秘的魔法门。但是&#xff0c;在魔法背后&#xff0c;我们也需要确保安全性&#xff0c;就像需要确保魔法不会落入邪恶之手一样。那么&#xff0c;基于Python的HTTP隧道在安全性方面表现如何呢&#xff1f;让我…

小区开店的成功秘诀:如何满足老年人的需求?

在鲜奶吧行业摸爬滚打 5 年&#xff0c;我深切体会到&#xff0c;要在小区成功开店&#xff0c;满足老年人的需求至关重要。以下是我总结的一些经验&#xff0c;希望能给想开鲜奶吧或正在创业的朋友们提供有价值的参考。 一、产品特色与健康理念 1、产品特色&#xff1a; 提…

生成树技术华为ICT网络赛道

9.生成树 目录 9.生成树 9.1.生成树技术概述 9.2.STP的基本概念及工作原理 9.3.STP的基础配置 9.4.RSTP对STP的改进 9.5.生成树技术进阶 9.1.生成树技术概述 技术背景&#xff1a;二层交换机网络的冗余性与环路 典型问题1&#xff1a;广播风暴 典型问题2&#xff1a;MA…

深入理解C语言(4):文件操作详解

文章主题&#xff1a;文件操作详解&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&#x…

洛谷_P1059 [NOIP2006 普及组] 明明的随机数_python写法

这道题的关键在于去重和排序&#xff0c;去重可以联想到集合&#xff0c;那排序直接使用sort方法。 n int(input()) data set(map(int,input().split( ))) data list(data) data.sort() print(len(data)) for i in data:print(i,end )