通过从左到右,从上到下设置索引,可以使用数组实现一些二叉树结构(例如堆)
0 / \ 1 2 / \ / \ 3 4 5 6 / \ / \ / \ / \ 7 8 9 10 11 12 13 14 ... etc.
索引x
的节点的子节点和父节点可以在O(1)中轻松找到:
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
。
我可以假设我的数组中永远不会有超过2个 32 元素,因此可以使用位移在O(1)中实现2 n 。也可能log_2
(???)
答案 0 :(得分:2)
好吧,我明白了。节点x的深度为
depth(x) = log2(x+1)
同样,可以很容易地找到节点x
的第i个左子节点和第i个右子节点:
ithLeftChild(x, i) = 2i(x+1) - 1 ithRightChild(x, i) = 2i(x+2) - 2
深度为d
的最左侧儿童的索引为ithLeftChild(x, d - depth(x))
,右侧儿童的索引类似。
让我们调用最后一个元素n
的索引。所以,现在我们可以找到n
的深度,我们还可以在该深度找到leftmostChild
和rightmostChild
的指示(可能比最后一个元素大,意思是它们实际上并不存在)。
现在我们只有三个案例:
n < leftmostChild
。然后我们的子树在该深度没有元素,因此最高索引必须是parent(rightmostChild)
。leftmostChild <= n <= rightmostChild
。那么最高指数必然是n
。rightmostChild < n
。然后rightmostChild
必须是我们的最高指数。 2 i 可以在O(1)中使用位移实现合理i
; log2(x)
可以在O(1)using a 256-byte lookup table中实现。因此整体算法 O(1)。