arrays - 在 O(1) 中确定基于数组的二叉树中的最低子节点(具有最大索引的后代)?

标签 arrays algorithm math data-structures binary-tree

一些二叉树结构(例如堆)可以通过设置从左到右、从上到下的索引来使用数组来实现

           0
      /        \
     1          2
   /   \      /   \
  3     4    5     6
 / \   / \  / \   / \
7   8 9 10 11 12 13 14
       ... etc.

可以在 O(1) 中轻松找到索引为 x 的节点的子节点和父节点:

child-left(x) = 2x+1
child-right(x) = 2x+2
parent(x) = (x-1)/2

但是有没有办法在 O(1) 中找到 x 的最低后代 (即索引最高的后代)?例如,在上面的树中,x=0 的最低后代为 14,而对于 x=1 则为 10。请注意,对于 x=1,如果树中只有 10 个元素,它应该返回 9

我可以假设我的数组中的元素永远不会超过 232,因此 2n 可以使用位移在 O(1) 中实现。也可能 log_2 (???)

最佳答案

嗯,我想通了。节点x的深度为

depth(x) = log2(x+1)

类似地,节点x的第i个左子节点和第i个右子节点很容易找到:

ithLeftChild(x, i) = 2i(x+1) - 1
ithRightChild(x, i) = 2i(x+2) - 2

深度最左边 child 的索引 dithLeftChild(x, d - depth(x)) , 右 child 也是如此。

我们称最后一个元素的索引为n .所以,现在我们可以找到 n 的深度, 我们还可以找到 leftmostChild 的指标和 rightmostChild在那个深度(可能比最后一个元素大,这意味着它们实际上并不存在)

现在我们只有三种情况:

  • n < leftmostChild .然后我们的子树在该深度没有元素,所以最高索引必须是 parent(rightmostChild) .
  • leftmostChild <= n <= rightmostChild .那么索引最高的必然是n .
  • rightmostChild < n .那么rightmostChild必须是我们的最高指数。

2i 可以在 O(1) 中实现合理的 i使用移位; log2(x)可以在 O(1) 中实现 using a 256-byte lookup table .所以整个算法是O(1)

关于arrays - 在 O(1) 中确定基于数组的二叉树中的最低子节点(具有最大索引的后代)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11509459/

相关文章:

iphone - 如何计算两个向量的平均方向

java - Java函数在返回参数时会复制参数传递的数组吗?

arrays - 使用 Start-Job 和 ArgumentList 如何传递数组和字符串值

algorithm - 大 O 符号(两侧)

java - 找到最大的子树

math - 半正定矩阵和数值稳定性?

c++ - 数组检查越界

java - 将 Zip 文件作为 InputStream,然后分离其中的每个文件,然后将其转换为图像。 java 语

string - Kickstart 2017(apac) 模式重叠

php - 替代 if(x >= 200 && x <= 299)?