如果我们从1开始构建最大堆过程到heap.length / 2而不是heap.length / 2到1,该怎么办?

时间:2017-07-19 19:04:38

标签: algorithm math data-structures

首先,这不是一个功课问题。 我正在研究CLRS,当我遇到一个查询时,如果我们以相反的方式(从1到a.length / 2)开始构建堆程序会发生什么。我想通过在一些堆上求解它而得到错误的结果(如如果没有证据证明这仅仅通过例子进行验证是正确的,我仍然无法完全满足自己。我试图在数学上证明它,但是在这个证明领域我是新手,所以我不知道从哪里开始。我如何证明通过数学?

关于如何以数学方式处理此类证据的任何建议对我都非常有帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

在原始解决方案中,您从长度/ 2开始,然后按下节点。问题是在length / 2 + 1和end之间你只有堆中的叶子节点。由于它们具有高度1(单个节点),因此它们中的每一个都是正确的堆。算法在每个步骤中执行的操作是创建一个新堆,其中根是一些随机值,但左右子树是有效堆(用于生成正确堆的推送操作的预先编码)。

当你走向另一个方向时,你推动第一个节点,但它的子树不是有效堆(它们是阵列中的任何一个)。因此推送操作无法保证正常工作。

如果你真的想从1构建堆,你需要只考虑你作为正确堆的一部分而触及的节点,算法正在做的是添加一个叶子并修复堆(通过一个流行操作)。请注意,在这种情况下,您无法在长度/ 2处停止,您需要一直走到最后。

从理论上讲,这两个解决方案都是O(NlogN),但是使用push操作会产生一个较小的常量(因为你只对一半的节点执行)并且平均运行速度更快。

对于证明,只需构造输入,其中第一个节点上的推送操作将不会执行任何操作,因为节点2和3更大/更小。很容易看出它并不意味着节点1是数组的最大值/最小值。

假设你正在做一个最小堆,你的输入是[1, 2, 3, 0, ...]