【问题标题】:Heap Bit-Shift Macros for Left, Right and Parent左、右和父的堆位移宏
【发布时间】:2017-01-07 14:14:51
【问题描述】:

我正在阅读堆,它描述了您可以执行访问左孩子,RIGHT/LEFT孩子和PARENT的操作strong> 带有位移操作。虽然 Left 和 Parent 似乎微不足道,但我不确定正确的。我只需要添加一个吗?

这是本书的摘录:MIT 算法简介:

“类似地,RIGHT 过程可以通过将 i 的二进制表示左移一位然后添加 1 作为低位来快速计算 2i + 1”。

访问操作:

左:2*i

i<<1

右:2*i+1

(i<<1)+1

父母:i/2

i>>1

【问题讨论】:

  • 怎么了?节点#3 的右子节点是节点#7,即(3 &lt;&lt; 1) + 1(注意&lt;&lt; 1,因为&lt;&lt; 2 将N 乘以4)
  • 添加一个 1 作为书中的低位对我来说听起来比仅仅做一个 +1
  • 这个问题对我来说仍然有点不清楚,但我试图解释N*2N*2 + 1背后的逻辑。如果您需要更多详细信息或解释,请告诉我
  • 很明显......我只是没有对位移做太多,我想知道我的操作是否正确。
  • 更新了答案,附有关于位移操作的注释

标签: python c++ algorithm heap


【解决方案1】:

这就是堆的工作原理 - 对于您可以轻松获得的每个节点:

  1. 父级 - 只需将节点索引除以 2 (N / 2)
  2. 左孩子 - 将索引乘以 2 (N * 2)
  3. 右孩子 - 将索引乘以 2 并将新索引增加 1 (N * 2 + 1)

很容易证明,两个不同的节点不能有相同的孩子。

假设N1N2C 是堆节点。 N1 != N2C.is_child_of(N1)C.is_child_of(N2),其中当 CN 的右子或左子时,C.is_child_of(N) 返回 true。那么:

  1. 如果CN1N2 的左孩子,那么N1 * 2 = N2 * 2 &lt;=&gt; N1 = N2
  2. 类似地,如果CN1N2 的右孩子,那么N1 * 2 + 1 = N2 * 2 + 1 &lt;=&gt; N1 = N2
  3. 如果CN1的左孩子,CN2的右孩子,那么N1 * 2 = N2 * 2 + 1是不正确的,因为N1 * 2是偶数,N2 * 2 + 1是奇数。

请注意,您的按位访问操作不正确 - 您应该将索引移动 1,而不是 2,因为 N &lt;&lt; MN * 2^M。我还建议您使用普通的除法/乘法而不是位移 - 编译器知道如何优化您的代码。

【讨论】:

  • 请注意,只有当您的堆的根位于数组中的索引 1 时,这才是正确的。对于基于 0 的堆,父堆位于 (n-1)/2,左子堆位于 (n*2)+1,右子堆位于 (n*2)+2
【解决方案2】:

Int i 上左移一位位置等价于2*i

如果我们将 i 视为数组的索引:
- 左孩子的索引可以使用:

i << 1

-右孩子的索引

(i<<1)+1

-父母:

i>>1

(相当于 i/2)

不要忘记我们在这种情况下考虑数组的初始索引是 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2014-12-22
    相关资源
    最近更新 更多