证明二叉堆构建最大比较是(2N-2)

2023-12-24

我试图证明对于二进制堆,buildHeap 最多会在元素之间进行 (2N-2) 次比较。 我发现很难证明这一说法。


构建堆算法从中点开始,并根据需要向下移动项目。让我们考虑 127 个项目(7 个级别)的堆。在最坏的情况下:

64 nodes (the leaf level) don't move at all
32 nodes move down one level
16 nodes move down two levels
 8 nodes move down three levels
 4 nodes move down four levels
 2 nodes move down five levels
 1 node moves down six levels

所以在最坏的情况下你有

64*0 + 32*1 + 16*2 + 8*3 + 4*4 + 2*5 + 1*6
0 + 32 + 32 + 24 + 16 + 10 + 6 = 120 swaps

因此,在最坏的情况下,构建堆进行的交换次数少于 N 次。

由于构建堆要求您交换具有最小子节点的项目,因此需要进行两次比较才能启动交换:一次比较是为了找到两个子节点中最小的节点,另一次是为了确定该节点是否更大并且必须交换。

移动节点所需的比较次数为2*(levels_moved+1),并且不会移动超过 N/2 个节点。

一般情况

我们需要证明最大比较次数不超过2N-2。正如我上面提到的,需要两次比较才能将节点移动一级。因此,如果移动的级别数小于 N(即 (N-1) 或更少),则最大比较次数不能超过 2N-2。

我在下面的讨论中使用完整堆,因为它代表最坏的情况。

在包含 N 个项目的完整堆中,叶级有 (N+1)/2 个节点。 (N+1)/4 在下一个级别。 (N+1)/8 下一个,依此类推。你最终会得到这样的结果:

(N+1)/2 nodes move 0 levels
(N+1)/4 nodes move 1 level
(N+1)/8 nodes move 2 levels
(N+1)/16 nodes move 3 levels
(N+1)/32 nodes move 4 levels
...

这给了我们这个系列:

((N+1)/2)*0 + ((N+1)/4)*1 + ((N+1)/8)*2 + ((N+1)/16)*3 ...

让我们看看这对于不同大小的堆有什么作用:

heap size  levels   levels moved
   1         1          0
   3         2          1
   7         3          2*1 + 1*2 = 4
   15        4          4*1 + 2*2 + 1*3 = 11
   31        5          8*1 + 4*2 + 2*3 + 1*4 = 26
   63        6          16*1 + 8*2 + 4*3 + 2*4 + 1*5 = 57
   127       7          32*1 + 16*2 + 8*3 + 4*4 + 2*5 + 1*6 = 120
         ....

我对最多 20 个级别的堆(大小为 100 万并发生变化)运行了该方法,结果成立:N 个项目的完整堆移动的最大级别数为 N-log2(N+1)。

以上述系列为算术几何数列 https://en.wikipedia.org/wiki/Arithmetico%E2%80%93geometric_sequence,我们计算总和log2(N + 1) - 1项,忽略第一项,因为它为零,等于N - 1。 (回想一下,满二叉树有log2(N + 1) levels)

该总和表示执行 siftup 操作的总次数。因此需要的比较总数是2N - 2(因为每个筛选操作都需要两次比较)。这也是上限,因为完整二叉树始终代表给定树深度的最坏情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

证明二叉堆构建最大比较是(2N-2) 的相关文章

  • 如何最小化两个子多边形的最大纵横比?

    我想使用直线将凸多边形切成给定面积比的两部分 以使两个子多边形的较大纵横比最小化 目前我的方法包括选择一个随机起点 计算将多边形分割成目标区域的适当终点 然后计算两个纵横比中较大的一个 然后重复这个很多次 直到我足够接近最小值 多边形 A
  • 二进制字符串到十进制字符串

    下午好 如何将字符数多于语言最大整数类型中位数的二进制字符串转换为十进制字符串 换句话说 假设你有字符串 111001101001110100100 1001001111011100100 并且您不能先将其转换为整数 那么您将如何以 10
  • C# 计算LRC(纵向冗余检查)

    我一直在到处研究这个问题 所有 LRC 实现似乎都没有给我正确的答案 花了几天时间后 我决定将我的代码放在这里 看看其他人是否可以发现问题 这是代码 C Input Data 31303030315E315E31303030325E315E
  • 给定两个(大)点集,我如何有效地找到彼此最接近的点对?

    我需要解决一个计算问题 该问题归结为搜索两个集合之间最接近的点对 问题是这样的 给定欧几里德空间中的一组点 A 和一组点 B 找到所有对 a b 使得 b 是 B 中与 a 最近的点 a 是 A 中与 b 最近的点 集合 A 和 B 的大小
  • Bellman-Ford 算法检测什么?负重还是负循环?

    如果给定一个图 现在我们要从源头计算最短路径 现在 如果一条边具有负权重 但在到达目的地时有边到后边返回到该边 我的意思是如果没有循环 那么我们就没有负循环 但是here http en wikipedia org wiki Bellman
  • 用于插入/删除/排名/选择查询的最佳数据结构/算法

    到目前为止 我知道像AVL树和红黑树这样的自平衡BST可以在O log n 次内完成这些操作 然而 要使用这些结构 我们必须自己实现AVL树或RB树 我听说有一个算法 实现这四个操作而不使用自平衡 BST 有了我们自己定义的结构 我们就需要
  • 稀疏矩阵中的最大和子矩形

    求一个子矩形中的最大和NxN矩阵可以完成O n 3 正如其他帖子中指出的 使用 2 d kadane 算法的时间 然而 如果矩阵是稀疏的 具体来说O n 非零条目 可以O n 3 时间被打败了吗 如果有帮助的话 对于我感兴趣的当前应用程序
  • 如何设置K-means openCV c++的初始中心

    我正在尝试使用 OpenCv 和 Kmeans 对图像进行分割 我刚刚实现的代码如下 include opencv2 objdetect objdetect hpp include opencv2 highgui highgui hpp i
  • 交换两个向量之间的值,使两个向量的 max_element 之和最小

    这是 Codechef 的问题 但请耐心等待 https www codechef com ZCOPRAC problems ZCO16001 https www codechef com ZCOPRAC problems ZCO16001
  • 加密成本高,解密成本低

    我希望该用户 攻击者加密数据并发送给服务器 现在我想要一种与标准算法完全相反的算法 使用快 难以解密 即很难使用服务器发送的密钥来加密密码等数据 以防止随机攻击 但很容易解密这样服务器在验证用户时消耗的时间非常少 但是对于攻击者来说 每次使
  • 反转二进制网络

    如何反转二元方程 以便找到哪些输入将产生给定的输出 Example Inputs i0 through i8 Outputs o0 through o8 Operators XOR AND 二元方程 1 i0 1 i1 0 i2 1 i3
  • Exposé 布局算法

    我正在制作一些项目 其布局类似于 Mac OS X 在 Expos 中对窗口所做的操作 它适应项目的长宽比和可用区域的长宽比 基本上 可用区域分为行和列 每个单元格 行和列的交集 中放置一个项目 这些项目必须保持其纵横比 此处width h
  • 从日志文件中获取前 100 个 URL

    我的一位朋友在接受采访时被问到以下问题 谁能告诉我如何解决它 我们有一个相当大的日志文件 大约 5GB 日志文件的每一行都包含一个用户在我们网站上访问过的 URL 我们想要找出用户访问最多的 100 个 URL 怎么做 如果我们有超过 10
  • 如何在给定目标索引数组的情况下对数组进行就地排序?

    你如何对给定的数组进行排序arr in place给定目标索引数组ind 例如 var arr A B C D E F var ind 4 0 5 2 1 3 rearrange arr ind console log arr gt B E
  • 如何查找给定字符串中仅出现一次的第一个字符[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何求解:T(n) = T(n - 1) + n

    我已经解决了以下问题 T n T n 1 n O n 2 现在 当我解决这个问题时 我发现界限非常松散 我是否做错了什么 或者只是这样 您还需要一个递归关系的基本情况 T 1 c T n T n 1 n 为了解决这个问题 您可以首先猜测一个
  • 通过分布式数据库聚合作业优化网络带宽

    我有一个分布式 联合数据库 结构如下 数据库分布在三个地理位置 节点 每个节点集群有多个数据库 关系数据库是 PostgreSQL MySQL Oracle 和 MS SQL Server 的混合体 非关系数据库是 MongoDB 或 Ca
  • 高维最近邻搜索的最佳数据结构

    我实际上正在处理高维数据 50 000 100 000 个特征 并且必须对其执行最近邻搜索 我知道随着维度的增长 KD 树的性能很差 而且我还了解到 一般来说 所有空间分区数据结构都倾向于对高维数据执行详尽的搜索 此外 还有两个重要事实需要
  • 最慢的计算复杂度(Big-O)

    在这些算法中 我知道 Alg1 是最快的 因为它是 n 平方的 接下来是 Alg4 因为它是 n 的立方 然后 Alg2 可能是最慢的 因为它是 2 n 这应该具有非常差的性能 然而Alg3和Alg5在我的阅读速度方面还没有遇到过 这两种算
  • 点集子集的最小周长凸包

    给定平面上的 n 个点 没有 3 个共线 给定数字 k 找到 k 个点的子集 使得 k 个点的凸包在 k 个点的子集的任何凸包中具有最小周长 我可以想到一个简单的方法 运行时间为 O n k k log k 找到大小为 k 的每个子集的凸包

随机推荐

  • UIKit 和单元测试

    我正在为我的 iPhone 应用程序实现一些测试用例 我已成功设置 UnitTest Target 如下所述 iPhone开发指南 http developer apple com iphone library documentation
  • Oracle 合并语句和按源/目标条件

    我需要做一个MERGE在 Oracle 中 但我被困住了 在 SQL Server 中 我总是使用BY SOURCE and BY TARGET检查记录存在的位置 然后采取行动 我有点困惑 因为我不知道如何在 PL SQL 中实现相同的目标
  • PHP - 计算字符串中逗号的数量

    如何计算逗号在这样的字符串中出现的次数 A B C D 它应该返回 3 substr count my string 如果您希望将逗号之间的所有元素作为数组获取 您可以随时 splitted explode my string
  • 从模式创建 ERD?

    我被告知要创建一个 ERD 图 给出以下内容 The college keeps track of each student s name student number social security number address phon
  • Ansible 自定义模块:可以打印语句吗?

    我有一个 Ansible 自定义模块 用于在我的剧本中执行特定任务 我想调试该模块内的特定变量 有没有办法可以打印这个自定义模块内的任何内容 在下面的示例中 打印 Hello 请检查自定义模块中的以下代码片段 我正在通过一个jobid作为该
  • 如何查找更改正在监视的对象的调用站点

    AngularJS 允许监听对象的变化 并调用提供给 watch 函数的回调函数 对于像 ngGrid 这样使用 AngularJS 的大型库 对象经常被 监视 一旦调用了监视回调 如何追溯到导致对象发生更改的调用站点 如果不知道是什么导致
  • 如何在 WordPress 中使用 get_current_user_id() ?

    我正在尝试弄清楚如何使用该功能get current user id 适当地 我需要它来分离用户数据 就像普通的 PHP 代码一样 SESSION 我找到了以下代码示例 并将其放入Function php它工作正常 但它似乎在每个页面上执行
  • PHP 查找最高键值的索引

    我有一个数组的数组 我想找到最高键值Rating的数组的索引 例如 下面的数组索引为 1 任何帮助将非常感激 array 3 0 gt array 3 name gt Nola Roman Road rating gt 4 2 price
  • Azure kubernetes - 具有内部负载均衡器的 Istio 控制器

    我有一个带有 Istio 服务网格的 Azure kubernetes 集群 目前 Istio 控制器与公共负载均衡器 IP 关联 我想使用内部负载均衡器配置 Istio 我将使用公共 IP 到内部 LB 的防火墙映射 如何配置 Istio
  • 如何将 GridView.DataSource 导出到数据表或数据集?

    我怎样才能导出GridView DataSource数据表或数据集 假设您的 DataSource 是 DataTable 类型 您可以这样做 myGridView DataSource as DataTable
  • 谷歌云消息传递示例[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有人有示例 gcm 服务器端和 android 项目吗 最好有一个解释一切的教程 我尝试查看示例中包含的内容 但未能成功 我有一个 c2d
  • maven-processor-plugin 忽略未定义的符号

    我有 JPA 2 maven 项目 我想处理源以获得静态元模型 我做了什么我拿走了JBoss 的静态元模型处理器 http docs jboss org hibernate stable orm topical html metamodel
  • 帮助循环遍历数组

    我在我的网站上进行了搜索 得到了以下数组 0 gt Array job id gt 4 job title gt Supercar Test Driver salary gt 40000 job tags gt Driving retrai
  • 在代码中复制 SQL Server 数据库

    我有两个 SQL Server 连接字符串 CX 和 CY 我需要做的是 确保 CY 中没有表 备份数据库CX 将其恢复为 CY 还没有找到我要找的东西 我不需要工具来执行此操作 我需要在运行时用 C 代码执行此操作 因为添加新客户端的操作
  • G++ 总是因对 _Unwind_GetIPInfo 的未定义引用而失败

    我刚刚在我的 Asus EeePC 上网本上升级到 Ubuntu 11 04 并且遇到了 G 问题 使用 G 编译任何程序 即使是简单的 Hello World 无论是使用 iostream cstdio 还是 stdio h 都会失败并显
  • 如何从子元素中删除 data-target 和 data-toggle 或禁用元素触发事件?

    HTML div class card panel span class white text text span div class card action each tags div class chip div div div
  • 如何使用 int 值将项目添加到表视图

    如何将数字添加到表格单元格并将数字添加到总标签 w当我添加像 ps2 这样的商品时 我怎样才能将价格添加到表格单元格并将其添加到我的总标签中 这是我三周以来一直试图解决的问题 到目前为止我的桌子 我的 ViewController swif
  • 通过 JSONProvider 重用类型定义?

    我正在使用 FSharp Data 中的 JSONProvider 自动为我使用来自服务的示例响应来使用的 Web 服务创建类型 然而 当涉及到在服务中重用的类型时 我有点困惑 例如 有一个 api 方法返回 X 类型的单个项目 而另一个返
  • SvelteKit 与 MongoDB ReferenceError:全局未定义

    我正在尝试设置 MongoDB 连接库功能 我知道这个功能很可靠 它用在很多地方 搜索此处使用 Global 来维护跨热重载的缓存连接 并且您会发现很多用途 包括 next js 版本 请注意 数据库连接全局存储的目的是减少任一时间使用的数
  • 证明二叉堆构建最大比较是(2N-2)

    我试图证明对于二进制堆 buildHeap 最多会在元素之间进行 2N 2 次比较 我发现很难证明这一说法 构建堆算法从中点开始 并根据需要向下移动项目 让我们考虑 127 个项目 7 个级别 的堆 在最坏的情况下 64 nodes the