数据结构(邓俊辉)学习笔记】优先级队列 03——完全二叉堆:结构

文章目录

  • 1.完全二叉树
  • 2.结构性
  • 3.形神具备
  • 4.堆序性

1.完全二叉树

在上一节我们看到,就优先级队列的实现方式而言,采用基本的向量结构并不足够,而采用更高级的树形结构,虽然完全可以高效率地实现优先级队列,但却有杀鸡用牛刀之嫌。那么能否在这两种策略之间设计一种折中的方案呢?
在这里插入图片描述

答案是肯定的,为此我们需要以向量为形,以树形结构为神,实现二者之间的有机结合。

在这里插入图片描述

为此,我们需要借助完全二叉树。所谓的 ”Complete Binary Tree“, 可以认为是 AVL 树的一个特例,其中的平衡因子处处非负。也就是说各节点的平衡因子或者为0,或者为 +1,但绝对不可能是-1。

而且对于树中的任何一个节点 V 而言,如果它的平衡因子为 0,那么左子树就必然是满树。另一种可能,如果 v 的平衡因子为 +1,那么它的右子树就必然是满树。由这些约定不难推知,就全局的拓扑结构而言,完全二叉树大致应该呈现为这样一种形式。

也就是说,如果忽略它的最底层,那么其余节点应该组成一棵满树。而最底层也只不过是缺失了右侧的连续一段。

2.结构性

在这里插入图片描述
比如,这就是一棵完全二叉树。可以看到,相对于满树,它的确只不过是在最底层的右侧缺失了连续的若干个节点。

现在回到优先级队列的实现问题,我们的思路是在逻辑上将优先级队列等同于一棵完全二叉树。而在物理上,我们却可以直接借助更为简明的向量来直接实现。 没错,通过向量来表示一棵完全二叉树,并且进而实现优先级队列。这一思路之所以可行,要得益于完全二叉树在结构上的紧凑性。

来看这样一个向量。没错,这就是一个向量,只不过为了便于与完全二叉树相对照,这里将它切分成了若干段。在这个例子中我们不难看出,完全二叉树中的每一个节点都与向量中的某一个节点相对应。

反过来,向量中的每一个元素也都与完全二叉树中的某一个节点相对应。更准确地讲,完全二叉树中的节点与向量中的元素之间是彼此一一互相对应的。是的,稍加观察就不难发现:在这里逻辑节点与物理元素之间的一一对应关系,与完全二叉树的层次遍历次序完全一致。

因此我们可以在向量内的各元素之间定义父与子的关系。具体来说,对于向量中任意秩为 i 的元素,它的父节点如果存在,其秩就必然等于(i - 1)/2。

比如对于秩为11和12的元素而言,它们的父节点的确存在,而且编号应该为5。

反过来,向量中秩为 i 的元素,如果拥有左孩子,那么左孩子所对应的秩就应该是 i * 2 + 1。

比如对于秩为6的这个元素而言,它的左孩子如果存在,它的秩应当是 6 * 2 +1 = 13,6的左孩子为13。

类似地,任何一个秩为 i 的元素,它的右孩子如果存在,那么它所对应的秩就应该是 (i + 1)* 2。

同样以这个秩为 6 的元素为例,其右孩子的秩应该是 (6 + 1)* 2 = 14,6的右孩子为14。

由此可见,我们的确可以在向量与完全二叉树之间建立这样一种对应的关系。请留意体会这种对应关系的精妙之处。实际上在物理上我们没有做任何的改动,所有的元素依然构成一个线性的向量。

但是,只要我们聪明地变化一下视角,站在这种对应关系的角度来重新审视这个向量,就会发现其实它的确是一个不折不扣的完全二叉树。这也为我们实现优先级队列提供了第一种可能。因为这种方法在逻辑上借助了完全二叉树,因此我们也将这种实现方法称作完全二叉堆。

那么具体的又当如何将向量的形与树”形“结构的“神”有机的融合起来呢?

3.形神具备

在这里,借助 C++语言中的多重继承特性,将向量模板类与优先级队列接口有机的融合起来,从而定义出完全二叉堆模板类。
在这里插入图片描述

这就是具体的实现方法,可以看到,这里的 PQ_ComplHeap 以公开的模式同时继承了 PriorityQueue 和 Vector 的特性。也就是说在物理上它自然就拥有了一个名为 elements 的可扩充数组。

另外一方面,作为 PriorityQueue 的派生类,它也自然应该提供我们此前所介绍的三种标准接口。此外还提供一个批量构造的接口,这些接口的实现方法我们都将在稍后逐一介绍。

当然,这些对外操作接口的实现还需要依赖若干内部的功能接口,我们也会在稍后相应地介绍它们。至此,我们已经在物理上的向量与逻辑的优先级队列之间初步地建立起了联系。然而,为了使得这种联系具有神采,我们还需要做另一方面的工作。

4.堆序性

在这里插入图片描述

如果说以上的结构性使得完全二叉堆拥有了血肉,那么堆序性就是它的灵魂。也就说,需要在完全二叉堆的所有节点之间定义某种次序。实际上,关于这一次序的约定并不复杂,简而言之,也就是任何一个节点在数值上都不会超过它的父亲。

请注意,在我们刚才所使用的这幅图中,每个节点上所标注的只是它所对应的元素在向量中的秩,而不是真正的数值。

而按照堆序性,任何节点都不得超过它的父亲。反过来,如果一个节点拥有左孩子和右孩子,那么在数值上,它也不会小于它的任何一个孩子。

回到优先级队列的功能接口,其中所涉及的最大元,在完全二叉堆中,又可能在哪里呢?根据堆序性不难推知,最大元只可能是根节点,难道不是吗?否则的话,如果最大元不再根节点处,那么就意味着它必然拥有父亲。而根据堆序性,它的父亲要比它更大。

刚才已经讲过,在物理上,根节点在向量中所对应的向量元素的秩应该必然是0。因此我马上就会发现,按照这种实现方法,getMax() 只需返回内部数组中的首元素。

好消息是,按照这样一种低成本的实现方式,其他的操作接口也同样能够高效率地加以实现。

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

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

相关文章

Codeforces Round 961 【C. Squaring】

C. Squaring 题目大意: 给你一个长度为n的数组,求最少次操作,使得数组(非严格)递增。一次操作:Ai 变为 Ai^2。 不可能实现输出-1。 关键思路: 分子分母同时取对数,比值不变。 …

流量日志分析

流量分析 [陇剑杯 2021]jwt(问1) 要求是通过流量分析判断网站使用的认证方式 在筛选http之后,发现有get请求,要认证方式就需要看请求流量包中的token 然后查看token tokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTAwOD…

动手学深度学习7.3 网络中的网络(NiN)-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:26 网络中的网络 NiN【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址:7.3. 网络…

三层架构与解耦——IoCDI机制【后端 7】

三层架构与解耦——IoC&DI机制 在软件开发领域,三层架构(Controller、Service、Dao)是一种广泛采用的架构模式,它通过将应用程序分为三个主要层次来组织代码,旨在提高代码的可维护性、复用性和可扩展性。而解耦&am…

怎么用dos编译python

无论windos还是Linux只要安装了python,配置好了环境变量,则在命令行输入python这个命令的时候就会进入交互模式。在这个模式下可以进行一些简单的python代码编写。退出可以使用exit()方法。 Python程序是可以执行的,例如下面代码&#xff0c…

文心一言 VS 讯飞星火 VS chatgpt (323)-- 算法导论22.4 4题

四、证明或反证下述论断:如果有向图G包含环路,则在算法TOPOLOGICAL-SORT(G)所生成的结点序列里,图G中与所生成序列不一致的“坏”边的条数最少。如果要写代码,请用go语言。 文心一言: 首先,我们需要明确几…

春秋云镜CVE-2023-38836

打开靶场环境 点击发现一个登陆框&#xff0c;弱口令试一下 发现账号密码为admin,password 随便点击点击 Media发现这里可以上传文件上传木马试试 <?php eval($_POST["wjq"]); ?> 发现不能上传php文件 php内容 修改他的格式 抓包绕过一下 302就可以其实已经…

同态加密和SEAL库的介绍(六)BGV 方案

前面介绍 BFV 和 CKKS 加密方案&#xff0c;这两者更为常用。并且也解释了 Batch Encoder 和 级别的概念&#xff0c;这对接下来演示 BGV 会很有帮助。 一、BGV简介 BGV (Brakerski-Gentry-Vaikuntanathan) 方案 是一种基于环学习同态加密&#xff08;RLWE&#xff09;问题的加…

华为OD笔试

机试总分400。三道题目。100&#xff0b;100&#xff0b;200 华为od考试时间为150分钟&#xff0c;共有三道编程题&#xff0c;分数分别为100、100和200。如果你是目标院校&#xff08;查看目标院校请戳&#xff09;的话&#xff0c;及格线是160分&#xff0c;非目标院校则不确…

论文阅读 - Scaling Up k-Clique Densest Subgraph Detection | SIGMOD 2023

1. 论文背景 密集子图发现&#xff08;Densest Subgraph Discovery&#xff09;是图挖掘领域的一个基础研究方向&#xff0c;并且近年来在多个应用领域得到了广泛研究。特别是在生物学、金融学和社交网络分析等领域&#xff0c;密集子图的发现对理解复杂网络结构和行为具有重要…

利用QT和FFmpeg实现一个简单的视频播放器

在当今的多媒体世界中&#xff0c;视频播放已成为不可或缺的一部分。从简单的媒体播放器到复杂的视频编辑软件&#xff0c;视频解码和显示技术无处不在。本示例使用Qt和FFmpeg构建一个简单的视频播放器。利用ffmpeg解码视频&#xff0c;通过QWidget渲染解码后的图像&#xff0c…

Python爬虫——爬取bilibili中的视频

爬取bilibili中的视频 本次爬取&#xff0c;还是运用的是requests方法 首先进入bilibili官网中&#xff0c;选取你想要爬取的视频&#xff0c;进入视频播放页面&#xff0c;按F12&#xff0c;将网络中的名称栏向上拉找到第一个并点击&#xff0c;可以在标头中&#xff0c;找到…

Ps:通过 RGB 值计算 HSB 值

在 Photoshop 中&#xff0c;HSB&#xff08;色相、饱和度和明度&#xff09;仅作为表达颜色的一种方式而存在&#xff0c;并不是一种颜色模式。 色相/饱和度命令就是基于色彩三要素进行调色的常用命令。 还有一个与 HSB 相关的滤镜&#xff1a;HSB/HSL 滤镜&#xff0c;用于实…

什么是交互测试?

最近有接触到一个有趣的名词&#xff1a;交互测试。 在对这个名词进行解释之前&#xff0c;我先去特意请教了一个产品经理朋友&#xff0c;问下交互的概念。于是知道了我们的行业里面还有很多个有趣的职位&#xff1a;交互设计师、UE、UI、前端、设计.....等等等等这些&#x…

C语言——查漏补缺

前言 本篇博客主要记录一些C语言的遗漏点&#xff0c;完成查漏补缺的工作&#xff0c;如果读者感兴趣&#xff0c;可以看看下面的内容。都是一些小点&#xff0c;下面进入正文部分。 1. 字符汇聚 编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 #inclu…

Linux:多线程(三.POSIX信号量、生产消费模型、线程池、其他常见的锁)

上次讲解了&#xff1a;Linux&#xff1a;多线程&#xff08;二.理解pthread_t、线程互斥与同步、基于阻塞队列的生产消费模型&#xff09; 文章目录 1.POSIX信号量1.1引入1.2回顾加深理解信号量1.3信号量的操作接口 2.基于循环队列的生产消费模型2.1循环队列2.2整个项目 3.线程…

网络协议七 应用层 HTTP 协议

应用层常见的协议 HTTP协议 一. 如何查看我们的http 协议全部的内容有哪些呢&#xff1f; 一种合理的方法是 通过 wireshark 软件&#xff0c;找到想要查看的HTTP --->追踪流--->HTTP流 来查看 结果如下&#xff1a;红色部分 为 发送给服务器的&#xff0c;蓝色部分为服…

40【源码】数据可视化:基于 Echarts + Python 动态实时大屏 - 无线网络大数据平台

数据可视化大屏的出现&#xff0c;掀起一番又一番的浪潮&#xff0c;众多企业主纷纷想要打造属于自己的“酷炫吊炸天”的霸道总裁大屏驾驶舱。 之前有小伙伴们建议我出一些视频课程来学习Echarts&#xff0c;这样可以更快上手&#xff0c;所以我就追星赶月的录制了《Echarts -…

为什么在职场上大家都在装,别人才会觉得你很强

在职场中&#xff0c;有时候会发现那些看似强大的人并不一定是真的强&#xff0c;而是他们懂得如何装出来。 上班就如甄嬛传里的宫斗&#xff0c;懂得“装”是一种智慧和生存技能。为什么在职场要会装&#xff1f;别人才会觉得你很强&#xff1f; 1、装冷脸形象没坏处 在职场…

C语言 | Leetcode C语言题解之第327题区间和的个数

题目&#xff1a; 题解&#xff1a; int countRangeSumRecursive(long long* sum, int lower, int upper, int left, int right) {if (left right) {return 0;} else {int mid (left right) / 2;int n1 countRangeSumRecursive(sum, lower, upper, left, mid);int n2 cou…