数据结构(邓俊辉)学习笔记】优先级队列 08——左式堆:结构

文章目录

  • 1. 第一印象
  • 2. 堆之合并
  • 3. 奇中求正
  • 4. NPL
  • 5. 左倾性
  • 6. 左展右敛

1. 第一印象

在学习过常规的完全二叉堆之后,我们再来学习优先级队列的另一变种,也就是左式堆。所谓的左式堆,也就是在拓扑形态上更加倾向于向左侧倾斜的一种堆,

比如这就是一个左式堆由生到长,直至灭亡的整个生命过程。
请添加图片描述
可以看到,相对于常规的完全二叉堆,左式堆的确显得有些别致。

那么,为什么要引入这一新的变种呢?让我们从它的设计动机以及结构定义说起。

2. 堆之合并

在这里插入图片描述

引入左式堆的动机非常直截了当,一言以蔽之,也就是为了能够有效地完成堆合并。具体的,对于任何的堆A 与堆 B,我们如何才能快速地将它们合二为一?

稍加思索,你可能会认为这并不是什么问题,因为借助已掌握的方法,我们完全可以实现这个功能。然而很遗憾,回到我们这门课程的核心,也就是计算效率。我们会发现已有的方法都不足用。

  1. 比如,可能会在两个堆中选择更大的那个作为基础,然后将另一堆中的元素逐一地取出并加入到前者当中,当更小的那个堆缩减为空时,也就自然完成了整体的合并。整个算法的描述也异常的简练,实际上主体的操作完全可以汇总为这样一句 A.insert(B.delMax())。

然而我们很快就会看到这个算法的效率是很低的,为此我们不妨将两个堆的规模分别记作 n 和 m,并且不失一般性地假设前者不小于后者,于是整个算法共需迭代 m 次,在每一次迭代中为了从 b 中摘除最大元,我们需要花费 log m 的时间,而为了将这个元素汇入到 a 中,我们又需要花费 log (n + m) 时间,总体而言我们大致需要 m *log n 的时间。至此,我相信你也会对这个效率不甚满意。是的,因为它的确存在改进的空间与可能。

  1. 是的,或许会想起 Floyd 批量建堆算法,实际上更为高效的一种办法就是将这两个堆中的元素首先简单地混合起来,然后借助 Floyd 算法将这 n + m 个元素整理为一个完全二叉堆,。

你应该记得 ,Floyd 算法只需线性时间,这一算法的效率明显优于此前的那个算法。然而即使是这个线性的效率,也依然不能令我们满意。你能看出我们不满意的原因吗?

没错,作为 Floyd 算法的输入在默认情况下,所有的元素都是无序排列。然而现在却不是这样,事实上它们被分成了两组,而且我们已经分别知道了它们内部的偏序关系,很遗憾刚才这个线性的算法却没有利用到我们已掌握的这些信息。

因此从这一角度出发,我们完全有理由相信应该会存在更为高效的数据结构及相应的算法。事实上,左式堆正是问题的答案。

3. 奇中求正

在这里插入图片描述

事实上,所谓的左式堆,也就是在保持堆序性的前提下,附加某种新的约束条件,从而使得在堆的合并过程中,我们只需调整少量的节点,事实上,只要这种结构及相应的算法设计得当,我们完全可以将所涉及的节点数目控制在 log(n) 的范围内。

  • 那么新引入的约束条件是什么呢?
    一言以蔽之,也就是所谓的单侧倾斜, 比如沿用发明者所确定的惯例,堆中各节点的分布会偏向于左侧,而相关算法之所以能够高效的诀窍在于,所有的合并操作只会涉及到全堆的右侧部分

    比如这就是左式堆的典型图解,所谓的向左侧倾斜,类比于书法,就相当于把撇写得更长,而捺写得更短。准确地讲,左式堆可以将右侧肩部的长度严格地控制在大 O 意义下的 log(n) 以内。可想而知,果真如此的话,我们就可以自然地将整体的时间复杂度控制在 log(n) 的范围之内。相对于我们刚才所介绍的那个线性算法,这不得不说是一个巨大的改进。

  • 那么这样一种特性是如何做到的呢?
    现在回答这个问题还嫌过早,因为我们首先还需要回答另一个问题。我们注意到如果真的有这样一个堆,那么它已经断乎不可能继续是一棵完全二叉树,也就是说尽管在此堆序性还有可能延续,而结构性却已荡然无存,无从谈起了。是的,的确如此。

    然后我们需要明白的是,对于堆结构而言,只有堆序性才是其本质的要求,而结构性却不是,在必要的时候结构性完全是可以牺牲掉的。

4. NPL

在这里插入图片描述

为了度量和判断左式堆的单侧倾斜性,我们需要引入一个概念,也就是所谓的"空节点路径长度"。

为便于讲解和理解,继续沿用之前在红黑树和 B 树中已经多次采用的一个技巧,也就是通过引入足够多个外部节点,将整个堆假想地转换为一棵真二叉树。
~  
比如,在上图中所有深色的节点都是原有的真实存在的节点,而所有浅色,也是方形的节点都是我们假想的引入的外部节点。可以看到经过这样一个转换,的确所有节点的度数都变成了偶数。

那么所谓的空节点路径长度(Null Path Length) 又是如何定义的呢? 首先作为基础,对于刚刚引入的每一个外部节点而言,其 NPL 值都统一设作0,而对于任何一个原本就存在的内部节点而言,为了确定它的 NPL 值,我们需要找到它的左孩子以及右孩子,并且在其中挑选出更小的 NPL 值。在已知的基础增加一个单位。

看到这个定义的表达式,你或许会想起点什么。没错,节点的高度。事实上,只要将这个 min() 换成 max(),也就是不折不扣的高度。通过这样的对比和类比,希望能够对这两个概念有更深刻的认识。

就这里的 NPL 而言,我们不难验证以下两个事实:

  1. 首先,任意节点 x 的NPL 值,必然等于 x 到所有外部节点的最近距离,比如任何一个外部节点的 NPL 值之所以为0,是因为它到所有外部节点的距离就是它自己到自己的距离,这个距离自然是0。

    再来看这个节点(上图第三排由左往右第3个)它的 NPL 值为什么是2呢?因为尽管它有一个外部节点的后代与它的距离为3,但这却不是最近的距离,实际上最近的距离应该实现于这样三个后代外部节点,而且这个距离恰好是2。

    类似地,这个例子中的根节点 NPL 值之所以为3,是因为这些外部节点到它的距离最近,而且这个距离都是3。

  2. 另一个可以验证的事实是,对于任何一个 x 而言,它的 NPL 值也是以它为根的那棵最大满树的高度。

    回到我们刚才的这个实例,依然考察 NPL 值为2的这个节点(上图第三排由左往右第3个),它的 NPL 值为2,我们也可以理解为存在一棵以它为根的高度为2的满树。

    事实上,对于其他的节点,也是如此:这个节点的 NPL 值为2(上图第二排由左往右第1个),是因为以它为根的极大满子树的高度也是2。而根节点的 NPL 值为3,也可以理解为以它为根的极大满子树的高度也是3。

至此,我们已经建立了 NPL 值这样一个重要的指标。以这个指标作为基准,我们就来度量堆结构的倾斜性。

5. 左倾性

在这里插入图片描述
是的,借助 NPL 这个指标,我们就可以简明地定义什么叫做左倾。也就是说对于任何一个节点 x, 如果在 NPL 的意义上,它的左孩子不小于它的右孩子,我们就称之为左倾。 如果在一个堆中,任何内部节点都是左倾的,我们就称这个堆为左倾堆,或者左式堆、左撇子堆。

当然根据 NPL 的定义,既然每个节点 x 的 NPL 值都是在它的孩子中间取一个小者,再累计上 1 个单位,于是很自然地在这个递推式中,我们就只需考虑每个节点的右孩子,而忽略它的左孩子。

不难确认,所谓的"左倾性"与我们此前的堆序性是彼此相容而不矛盾的。

既然左倾性是必须处处满足的,所以我们也自然地可以推知,任何一个左式堆的任何一个子堆必定依然是左式堆。

不难理解,作为左式堆,它更倾向于将更多的节点分布于左侧的分支,正像我们最初所希望的那样。然而需要指出的是,这只是一个大致的倾向,事实情况未必严格如此。

可以进一步来思考这样两个问题:

  1. 也就是在左式堆中,是否左子堆的规模总是大于右子堆?
  2. 另外左子堆的高度是否也必然总是大于右子堆?

在这里我们也给出了一个左式堆的具体实例(上图),而刚才两个问题答案也就藏在这个实例当中。

6. 左展右敛

在这里插入图片描述

实际上对于左式堆而言,左子堆和右子堆在规模和高度上的差异并不是那么重要,真正重要的是全堆的右侧链。

在以 x 为根的任何一个子堆中,从这个节点出发,一路向右,不断前行所确立的那个分支就称作为右侧链。

特别地,对于全树根节点而言,它的右侧链的终点必然是全堆中深度最小的一个外部节点。

比如在上图中,相对于根节点 r,它所对应的右侧链的终点应该是这个外部节点。

刚刚介绍过,在左式堆中 r 的 NPL 值必然是在它的右孩子基础上累进一个单位。而它的右孩子也必然是在它的右孩子基础上累进一个单位。

如此递推,可以得知所谓 NPL(r)值必然是在这个终端节点, NPL 值也就是0的基础上不断累进而得。因此,如果 r 的 NPL 值为 d,则不仅意味着这个外部节点的深度也是 d,而且更重要地,按照我刚才的结论,必然存在一棵以 r 为根的高度为 d 的极大满子树。这一点对于左式堆来说至关重要,事实上这就意味着在左式堆中应该包含足够多个节点。

因为即便我们只记录这棵满子树,也至少应该有 2 d + 1 − 1 2^{d + 1} - 1 2d+11 个节点。当然,其中也至少包含 2 d − 1 2^d - 1 2d1个内部节点。没错,如果根节点的 NPL 值为 d,那么其中就至少含有 2 d 2^d 2d个节点。

反过来,如果将左式堆的规模固定为 n,那么右侧链的长度 d 也就至多不过 log n。没错,右侧链的长度至多为 log(n)。这难道不正是我们最初的设计目标吗? 因此进一步地,如果我们所设计的堆合并算法的确也能将操作的范围限定在右侧链,那么相关算法的复杂度就很自然地也同样可以控制在log(n)的范围。那么这样的算法到底是如何运转的呢?

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

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

相关文章

嵌入式学习——ARM学习(1)

1、存储器 高速缓存(Cache)通常分为三级:L1、L2 和 L3。它们的主要功能和特点如下: 这三级缓存的设计旨在通过层次化存储来优化数据访问速度和处理器性能。 1、L1 缓存: 位置:直接集成在处理器核心内。 大小…

ios去水印软件免费版,精选五大高效工具,告别水印烦恼!

随着社交媒体的普及,越来越多的人喜欢在网络上分享自己的生活点滴。在分享视频时,水印往往会影响美观。为了帮助大家解决这个问题,本文为您推荐五大高效免费的iOS去水印软件,让您轻松告别水印烦恼! 软件一&#xff1a…

​拼多多:这一刀 砍向了自己

到处砍一刀,砍赢淘宝、京东,称霸中国电商的—— 拼多多 竟然刀刃向内,砍了自己一刀? 营收增长86%,净利润增长了144%,上半年净利润600亿,半年赚了去年全年的利润。 拼多多交出一份足以傲视全球…

Iptables-快速上手

Iptables firewall 防火墙Iptables简述一、Iptables的四表五链1.filter表2.nat表3.raw表4. mangle表5.数据包的流通过程 二、快速上手1. 查看规则2. 规则详细3. 添加规则4. 自定义链 三、关于iptables和docker1. 背景2. 解决方案 firewall 防火墙 从逻辑上讲,可以分…

【LLM之Data】SKYSCRIPT-100M论文阅读笔记

研究背景 随着短视频和短剧的兴起,自动化的剧本生成和短剧制作在影视行业中的需求逐渐增加。传统的剧本生成过程需要大量的人工干预,限制了其在规模和效率上的扩展性。当前的大型语言模型(LLM)在剧本生成方面展现出一定潜力&…

K8S的持久化存储

文章目录 一、持久化存储emptyDir实际操作 hostPath建立过程 NFS存储NFS 存储的优点NFS 存储的缺点具体操作 pv和pvcPersistent Volume (PV)使用场景 Persistent Volume Claim (PVC)使用场景 使用 PV 和 PVC 的场景实际操作 StorageClassStorageClass 概述应用场景实际应用 一、…

CLIP微调方法总结

文章目录 前言1️⃣ Tip-Adapter论文和源码原理介绍 2️⃣Cross-modal Adaptation(跨模态适应)论文和源码原理介绍 3️⃣ FD-Align(Feature Discrimination Alignment,特征判别对齐)论文和源码原理介绍 总结 前言 本文…

USB3.2 摘录(11)

系列文章目录 USB3.2 摘录(一) USB3.2 摘录(二) USB3.2 摘录(三) USB3.2 摘录(四) USB3.2 摘录(五) USB3.2 摘录(六) USB3.2 摘录&…

IO进程day01(标准IO、缓存区)

目录 【1】标准IO 1》概念: 2》特点 【2】缓存区 1》全缓存:和文件相关 2》行缓存:和终端有关 3》不缓存:也就是没有缓存区,标准错误。 【1】标准IO 1》概念: 标准IO: 是在C库中定义的一…

C++ | Leetcode C++题解之第355题设计推特

题目&#xff1a; 题解&#xff1a; class Twitter {struct Node {// 哈希表存储关注人的 Idunordered_set<int> followee;// 用链表存储 tweetIdlist<int> tweet;};// getNewsFeed 检索的推文的上限以及 tweetId 的时间戳int recentMax, time;// tweetId 对应发送…

香港站群服务器优势

香港站群服务器因其独特的地理位置和网络连接优势&#xff0c;在SEO优化、网站群管理和网络营销等方面受到广泛关注。其优势主要体现在以下几个方面&#xff0c;rak小编为您整理发布。 地理位置优越 连接亚洲国际市场&#xff1a;香港作为亚太地区的重要经济中心&#xff0c;具…

代码随想录 刷题记录-18 动态规划(2)01背包问题、习题

一、01背包理论基础 例题&#xff1a;46. 携带研究材料 01 背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 暴力解法&#xff1a…

SpringBoot实现Word转PDF/TXT

背景 研发工作中难免会遇到一些奇奇怪怪的需求&#xff0c;就比如最近&#xff0c;客户提了个新需求&#xff1a;上传一个WORD文档&#xff0c;要求通过系统把该文档转换成PDF和TXT。客户的需求是没得商量的&#xff0c;必须实现&#xff01;承载着客户的期望&#xff0c;我开始…

【计算机网络】应用层HTTP协议

我们已经实现过应用层协议&#xff0c;但也要看一看成熟的应用层协议 目录 1 HTTP协议11 URL12 urlencode 和 urldecode13 HTTP 协议请求与响应格式请求格式响应格式 14 界面的基本处理显示基本主页显示图片页面跳转 15 常见header16 状态码161 404举例162 关于3开头的状态码 1…

yd云手机登录算法分析

yd云手机登录算法分析 yd云手机登录算法分析第一步&#xff1a;抓包-登录第二步&#xff1a;定位加密入口第三步&#xff1a;分析加密算法第四步&#xff1a;算法实现 yd云手机登录算法分析 在这篇文章中&#xff0c;我们将详细解析yd云手机的登录算法&#xff0c;涵盖从抓包到…

96.SAP MII功能详解(09)Workbench-Transaction Debugging

目录 1.About Transaction Debugging Use Features Activities 2.How to Debug Start Debugging Create Breakpoint Watch Variables Debugging logs 1.About Transaction Debugging Use You use this function to monitor and manipulate a transaction while it …

微深节能 堆取料机回转俯仰角度检测系统 格雷母线定位系统

微深节能在堆取料机回转俯仰角度检测系统中引入的格雷母线定位系统&#xff0c;是一项重要的技术创新&#xff0c;显著提升了堆取料作业的自动化水平和精确性。以下是对该系统的详细介绍&#xff1a; 一、系统概述 格雷母线定位系统作为高精度、无磨损的非接触式位置检测系统&a…

07 - procfs

---- 整理自 王利涛老师 课程 实验环境&#xff1a;宅学部落 www.zhaixue.cc 文章目录 1. procfs 快速入门2. procfs 文件创建的回调机制3. 在 proc 目录下创建子目录4. 通过 proc 接口修改内核变量5. 通过 proc 接口访问数组6. 序列文件&#xff1a;seq_file 编程接口7. seq_f…

OpenCV绘图函数(1)绘制带箭头的直线函数arrowedLine()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 绘制一个从第一个点指向第二个点的箭头线段。 cv::arrowedLine 函数在图像中绘制一个从 pt1 到 pt2 的箭头。另见 line 函数。 函数原型 void c…

基于单片机的无线空气质量检测系统设计

本设计以STC89C52单片机为核心&#xff0c;其中包含了温湿度检测模块、光照检测模块、PM2.5检测模块、报警电路、LCD显示屏显示电路、按键输入模块和无线传输模块来完成工作。首先&#xff0c;系统可以通过按键输入模块设置当前的时间和报警值&#xff1b;使用检测模块检测当前…