Mit6.006-lecture08-BinaryHeaps

news2025/1/11 10:54:55

一、优先队列接口

  • 记录一些项目,快速地访问/移除最重要的

    • 例:有限带宽的路由器,必须优先某些信息

    • 例:操作系统内核中的进程调度

    • 例:离散事件模拟(下一件事何时发生)

    • 例:图算法(接下来的课程中)

  • 通过key有序的项目=优先,因此是集合接口(不是序列接口)

  • 对集合特定操作子集进行了优化:

    • build(X),由可迭代的X构建优先队列

    • insert(x),添加项目x到数据结构

    • delete_max(),移除并返回拥有最大key的存储项目

    • find_max(),返回拥有最大key的存储项目

  • 通常对最大或最小做出优化,而非全部

  • 聚焦于insert和delete_max操作:build可以重复地insert;find_max可以是insert(delete_max())

二、优先队列排序

  • 任何优先队列数据结构可以翻译为排序算法:

    • build(A),按输入顺序,一个一个地插入项目

    • 重复地delete_min(或delete_max())来决定(反向)顺序

  • 所有艰难的工作发生在数据结构中

  • 运行时间是: T b u i l d + n ∗ T d e l e t e _ m a x ≤ n ∗ T i n s e r t + n ∗ T d e l e t e _ m a x T_{build}+n*T_{delete\_max}\le n*T_{insert}+n*T_{delete\_max} Tbuild+nTdelete_maxnTinsert+nTdelete_max

    我们已经看到的一些排序算法,可以被视作优先队列排序:

三、优先队列:集合AVL树

  • 集合AVL树支持insert(x),find_min(),find_max(),delete_min(),delete_max()花费 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)

  • 因此优先队列排序花费 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn)

    • 这源自lecture 7的AVL排序
  • 可以通过子树新增变量,加速find_min()和find_max()为耗时 O ( 1 ) \mathcal{O}(1) O(1)

  • 但这个数据结构是复杂的,结果排序是非in-place的

  • 是否存在一个更简单的数据结构用于优先队列,并且是 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn) 时间复杂度的in-place排序?存在,二项堆和堆排序

  • 在序列数据结构(数组)之上,实现集合数据结构,使用我们学过的二叉树

四、优先队列:数组

  • 存储项目到一个无序动态数组

  • insert(x):追加x到最后,花费摊还 O ( 1 ) \mathcal{O}(1) O(1)

  • delete_max():花费 O ( n ) \mathcal{O}(n) O(n)找到最大的,交换最大的到最后,然后删除

  • insert是快的,但delete_max是慢的

  • 优先队列排序是选择排序!(加上一些拷贝)

五、优先队列:有序数组

  • 存储项目到有序动态数组

  • insert(x):在末尾追加x,花费 O ( n ) \mathcal{O}(n) O(n)交换到有序的位置

  • delete_max():从末尾删除花费摊还 O ( 1 ) \mathcal{O}(1) O(1)

  • 优先队列排序是插入排序!(加上一些拷贝)

  • 我们可以从两个极端的数组优先队列中找到折中?

六、数组作为一个完全的二叉树

  • 想法:数组表示完全二叉树,除最大深度外,深度i处有 2 i 2^i 2i个点,所有点左对齐。

  • 等价地,完全二叉数阅读顺序:从根到叶子、从左到右

  • 数组和完全二叉树的双射

  • 对应n个元素数组的完全二叉树高度为 ⌈ lg ⁡ n ⌉ \lceil \lg n \rceil lgn,因此是平衡二叉树

七、隐式完全二叉树

  • 完全二叉树结构可以是隐式的,而非存储指针

  • 根在索引0处

  • 通过索引算式计算相邻点:left(i)=2i+1,right(i)=2i+2,parent(i)= ⌊ i − 1 2 ⌋ \lfloor \frac {i-1}{2} \rfloor 2i1

八、二叉堆

  • 想法:更大的元素在树中高度更高,仅局部如此

  • 节点i处最大堆属性: Q [ i ] ≥ Q [ j ] , j ∈ { l e f t ( i ) , r i g h t ( i ) } Q[i]\ge Q[j],j\in\{left(i),right(i)\} Q[i]Q[j],j{left(i),right(i)}

  • 最大堆是一个数组:所有节点满足最大堆属性

  • 声明:在最大堆中,对于subtree(i)中所有节点j,每个节点i满足 Q [ i ] ≥ Q [ j ] Q[i]\ge Q[j] Q[i]Q[j]

  • 特别地,最大项目在最大堆的根部

九、堆插入

  • 追加新项目x到数组末尾,耗费摊还 O ( 1 ) \mathcal{O}(1) O(1),生成它的下个叶子i(按读顺序)

  • max_heapify_up(i):与parent交换,直到满足最大堆属性

    • 检测 Q [ p a r e n t ( i ) ] ≥ Q [ i ] Q[parent(i)]\ge Q[i] Q[parent(i)]Q[i](parent(i)处最大堆属性的一部分)

    • 如果不是,交换Q[i]和Q[parent(i)],递归max_heapify_up(parent(i))

  • 正确性:

    • 最大堆属性保证所有节点>=子节点

    • 如果必须交换,Q[parent(i)]满足同样的保证,而非Q[i]

  • 运行时间:树的高度,因此是 Θ ( log ⁡ n ) \Theta(\log n) Θ(logn)

十、堆删除最大

  • 仅可以轻松地从动态数组中移除最后的项目,但最大的key是树的根

  • 因此把根节点(i=0处的项目)与最后的项目(n-1处)交换

  • max_heapify_down(i):将根与更大的子节点交换,直到满足最大堆属性

    • 检查是否 Q [ i ] ≥ Q [ j ] , j ∈ { l e f t ( i ) , r i g h t ( i ) } Q[i]\ge Q[j],j \in \{left(i),right(i)\} Q[i]Q[j],j{left(i),right(i)}(位于i处的最大堆属性)

    • 如果不是,Q[i]和Q[j]进行交换( j ∈ { l e f t ( i ) , r i g h t ( i ) } j\in\{left(i),right(i)\} j{left(i),right(i)},有最大key的项目),并递归调用max_heapify_down(j)

  • 正确性:

    • 最大堆属性保证所有节点>=子节点

    • 如果必须交换,Q[j]满足同样的保证,而非Q[i]

  • 运行时间:树的高度,因此是 Θ ( log ⁡ n ) \Theta(\log n) Θ(logn)

十一、堆排序

  • 添加最大堆到优先队列排序,给我们一个新的排序算法

  • 运行时间是 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn),因为每个insert和delete_max花费 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)

  • 对于这个排序算法,通常包含两个提升

十二、in-place优先队列排序

  • 最大堆Q是一个更大数组A的前缀,记录共有多少项目在堆中

  • ∣ Q ∣ |Q| Q初始时为0,最终为 ∣ A ∣ |A| A(插入完),然后再次为0(删除后)

  • insert()吸收数组中下个项目(位于索引 ∣ Q ∣ |Q| Q处)到堆

  • delete_max()将最大的项目移到最后,然后通过降低 ∣ Q ∣ |Q| Q来废弃它

  • 数组in-place优先队列排序是选择排序

  • 有序数组in-place优先队列排序是插入排序

  • 二叉最大堆in-place优先队列排序是堆排序

十三、线性构建堆

  • 插入n个项目到堆中,i从0到n-1调用max_heapify_up(i)(根下降):

最坏情形交换: ∑ i = 0 n − 1 d e p t h ( i ) = ∑ i = 0 n − 1 lg ⁡ i = lg ⁡ ( n ! ) ≥ ( n / 2 ) lg ⁡ ( n / 2 ) = Ω ( n lg ⁡ n ) \sum_{i=0}^{n-1}depth(i)=\sum_{i=0}^{n-1}\lg i=\lg(n!)\ge(n/2)\lg(n/2)=\Omega(n\lg n) i=0n1depth(i)=i=0n1lgi=lg(n!)(n/2)lg(n/2)=Ω(nlgn)

  • 将整个数组当作一个完全二叉树,i从n-1到0调用max_heapify_down(i)(叶子上升):

最坏情形交换: ∑ i = 0 n − 1 h e i g h t ( i ) = ∑ i = 0 n − 1 ( lg ⁡ n − lg ⁡ i ) = lg ⁡ n n n ! = Θ ( lg ⁡ n n n ( n / e ) n ) = O ( n ) \sum_{i=0}^{n-1}height(i)=\sum_{i=0}^{n-1}(\lg n-\lg i)=\lg \frac{n^n}{n!}=\Theta(\lg \frac{n^n}{\sqrt n(n/e)^n})=\mathcal{O}(n) i=0n1height(i)=i=0n1(lgnlgi)=lgn!nn=Θ(lgn (n/e)nnn)=O(n)

  • 因此可以花费 O ( n ) \mathcal{O}(n) O(n)构建堆

  • 没有加速堆排序的性能( O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn)

十四、序列AVL树优先队列

  • 其他线性构建时间的对数数据结构,序列AVL树

  • 以任意顺序(插入顺序)存储优先队列项目到序列AVL树

  • 维持最大新增变量:node.max=指向node子树中拥有最大key的节点,这是一个子树属性,因此花费常量复杂度

  • find_min()和find_max()花费 O ( 1 ) \mathcal{O}(1) O(1)

  • delete_min和delete_max花费 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)

  • build(A)花费 O ( n ) \mathcal{O}(n) O(n)

  • 与二叉堆有相同的边界

十五、Set和Multiset

  • 我们的集合接口假定没有重复key,我们可以使用这些集合实现Multiset,允许项目有重复key

    • 集合中的每个项目是一个序列(比如链表),存储了有同一个key的多个项目
  • 实际上,除了这个方法,二叉堆和AVL树可以直接处理重复key的项目(比如delete_max删除有最大key的所有项目),注意使用<=,而不是集合AVL树中的<

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

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

相关文章

js程序运行时在本机与外部app交互

js程序运行时在本机与外部app交互 目录 js程序运行时在本机与外部app交互 一、序言 1.1、问题 1.2、简要回答 二、原理 2.1、插件/web扩展/应用配置/权限 2.2、获取权限-原生应用交换信息的权限nativeMessaging 2.2.1、runtime(运行时的API) 2.3、连接本地应用程序的…

《微服务实战》 第十四章 RabbitMQ应用

前言 一般MQ用于系统解耦、削峰使用,常见于微服务、业务活动等场景。 1、RabbitMQ概念概念 RabbitMQ整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。 1.1、生产者和消费者 Producer:生产者,就是投递消息的一方。消息一般可以包含2个部分:消息体和标签…

Vue3+i18n多语言动态国际化设置步骤

1、技术介绍 i18n&#xff1a;Vue.js 的国际化插件。它可以轻松地将一些本地化功能集成到你的 Vue.js 应用程序中 i18n的官网地址安装 | Vue I18n (kazupon.github.io) 2、插件安装 npm install vue-i18n9 --save需要注意的是vue3最好使用9.x以上的版本&#xff01; 3、创建i…

夏日挂脖风扇方案开发设计

夏日挂脖风扇是一种便携式的风扇设备&#xff0c;通过挂在用户的脖子上&#xff0c;为用户提供清凉的风力降温。在夏季高温天气中&#xff0c;挂脖风扇成为了人们追逐的热门产品之一。为了满足市场需求&#xff0c;夏日挂脖风扇的方案开发设计需要考虑多个方面&#xff0c;包括…

Class 09 - Data Frame和查看数据

Class 09 - Data Frame和查看数据 DataFrametibbleshead()str()colnames()mutate()创建 Dataframe DataFrame 在我们开始做数据清洗或者检查数据是否存在偏差之前&#xff0c;我们需要先将我们的数据转换成合适的格式方便我们做后续的处理。 这就要说到DataFrame了。因为他很…

CSDN programmer_ada what the hell

CSDN programmer_ada 1、今天博客收到了1条评论&#xff0c;莫名其妙。2、查看这个账户 原来是CSDN官方机器人3、貌似领了红包 就会自动关注发红包的账户 1、今天博客收到了1条评论&#xff0c;莫名其妙。 一定要坚持创作更多高质量博客哦, 小小红包, 以资鼓励, 更多创作活动请…

【ClickHouse】什么是ClickHouse?CK入门

文章目录 一、ClickHouse入门1、列式存储2、DBMS的功能3、多样化引擎4、高吞吐写入能力5、数据分区与线程级并行6、性能对比7、官网 二、ClickHouse安装1、准备工作2、单机安装 三、ClickHouse的数据类型1、整型2、浮点型3、布尔型4、Decimal型6、枚举类型7、时间类型8、数组 一…

好程序员:女生学Java好学吗?女生学Java有什么优势?

小源经常会听到女生咨询适不适合学习Java开发的问题&#xff0c;提出这种问题归根结底还是缺乏性别自信&#xff0c;默认女性比男性弱。实际上这个问题并不存在&#xff0c;男女平等才是正确的思维&#xff0c;当然&#xff0c;也为了解开女生们的心结&#xff0c;这里好程序员…

开发微信公众号本地调试+-+cpolar内网穿透

文章目录 前言1. 配置本地服务器2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道 3. 测试公网访问4. 固定域名4.1 保留一个二级子域名4.2 配置二级子域名 5. 使用固定二级子域名进行微信开发 转载自cpolar内网穿透的文章&#xff1a;微信公众号开发&#xff1a;对接本地开发…

股票?看我用python采集数据制作成交量图表

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 开发环境 & 第三方模块: 解释器版本: python 3.8 代码编辑器: pycharm 2021.2 requests: pip install requests 爬虫 pyecharts: pip install pyecharts 数据分析 pandas: pip install pandas 数据分析 基本流…

C++常用的支持中文的GUI库Qt 6之一:下载、安装与简单使用

C常用的支持中文的GUI库Qt 6之一&#xff1a;下载、安装与简单使用 因为Qt发展变化较快&#xff0c;网上许多介绍Qt的下载、安装与使用已过时&#xff0c;初学者常因行不通而受挫&#xff0c;故此发布本文&#xff0c;以Qt 6.2.4开源版在Windows 10安装与使用为例介绍。 C好用…

Kubernetes 之7大CNI 网络插件用法和对比

Kubernetes 它需要网络插件来提供集群内部和集群外部的网络通信。以下是一些常用的 k8s 网络插件&#xff1a; Flannel&#xff1a;Flannel 是最常用的 k8s 网络插件之一&#xff0c;它使用了虚拟网络技术来实现容器之间的通信&#xff0c;支持多种网络后端&#xff0c;如 VXLA…

SpringSecurity权限管理基本概念和整体架构介绍

文章目录 一、权限管理1、认证2、授权3、对权限控制&#xff0c;现有的解决方案 二、SpringSecurity简介1、官方定义2、历史 三、整体架构1、认证AuthenticationManagerAuthenticationSecurityContextHolder 2、授权AccessDecisionManagerAccessDecisionVoterConfigAttribute 一…

SQL注入:sqli第一关详细讲解

一、实验环境&#xff1a; Apache2.4.39 FTP0.9.60 MySQL5.7.26 PHP 5.3.29(注意PHP的版本不应过高&#xff0c;否则会导致sqli安装失败) sqli 二、实验步骤 第一步&#xff1a;在id1后加入一个闭合符号&#xff0c;如果报错&#xff0c;再在后面加上 -- qwe将后面注释掉…

vivado中的FPGA时钟管理单元PLL学习记录

vivado中的FPGA时钟管理单元PLL学习记录 CMT简介一、PLL IP的使用1、ip调用 2、生成的频率限制二、PLL实现原理 三、使用过程中的问题程序注意事项 CMT简介 FPGA中时钟管理模块&#xff08;CMT&#xff09;包括PLL和MMCM&#xff0c;用于将时钟倍频(比如输入时钟25M&#xff0…

第三方实验室云LIS系统

本套云LIS系统基于B/S架构的实验室管理系统&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。SaaS服务&#xff0c;无需部署&#xff0c;开通账号接口快速入门使用&#xff0c;集齐前处理、检验、报告、质控、统计分析…

测试自动化_Katalon

测试自动化_Katalon 1.概述 ​ Katalon界面的自动化测试工具&#xff0c;简称KS&#xff0c;于2015年推出。是开源的&#xff0c;提供的版本有免费的版本&#xff0c;还有企业版是收费的。如下图。其中的服务台功能应该是持续继承的支持。可试用一个月。 ​ 最初是支持Web UI…

Baumer工业相机堡盟工业相机通过BGAPISDK使用图像回调函数全帧率保存图像 (C#)

Baumer工业相机堡盟工业相机通过BGAPISDK使用图像回调函数全帧率保存图像 &#xff08;C#&#xff09; Baumer工业相机Baumer工业相机全帧率保存的技术背景Baumer工业相机通过BGAPISDK使用相机图像回调函数1.引用合适的类文件2.通过BGAPISDK在相机图像回调函数全帧率保存 Baume…

2023年湖北建筑电工报名需要什么资料 ?报考条件是什么?启程别

2023年湖北建筑电工报名需要什么资料 &#xff1f;报考条件是什么&#xff1f;启程别 建筑电工证&#xff0c;适合在建筑工地上、建筑公司里面使用&#xff0c;和应急管理局的电工证是不同的&#xff01;建筑电工证也称之为建筑特操&#xff0c;统称建筑施工特种作业操作资格证…

如何成为ITSMS、ISMS审核员

一、管理体系审核员的注册领域 管理体系审核员包括质量管理体系&#xff08;QMS&#xff09;、环境管理体系&#xff08;EMS&#xff09;、职业健康安全管理体系&#xff08;OHSMS&#xff09;、食品安全管理体系&#xff08;FSMS&#xff09;、危害分析与关键控制点&#xff0…