You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在深度优先顺序的隐式二叉树中快速确定左右节点索引?

完美二叉树DFS存储中,从节点索引i和整树高度H推导子树高度hᵢ

问题背景

我们知道,完美二叉树按**Eytzinger顺序(层序/广度优先遍历)**存储时,1-based索引下内部节点i的左右子节点索引为2i和2i+1,规则非常直观。

但如果按前序深度优先遍历顺序存储节点,节点i的左右子节点索引计算依赖于该节点子树的高度hᵢ:

  • 左子节点索引:i+1
  • 右子节点索引:i + 2^(hᵢ-1) - 1(其中2^(hᵢ-1)-1是左子树的节点总数)

如果每次传递高度信息可行,但我们希望直接从i和整树高度H优雅高效地推导hᵢ,替代时间复杂度O(H)的循环解法。

最优解法:O(1)直接推导

公式推导

对于完美二叉树的前序DFS存储,子树高度hᵢ可以通过以下公式直接计算:

hᵢ = H - floor(log₂(i))

其中floor(log₂(i))是i的二进制表示中最高位对应的指数(即最大的整数k满足2ᵏ ≤ i)。

验证示例

以整树高度H=3为例(总节点数7,前序DFS顺序为:1→2→4→5→3→6→7):

  • i=1(根节点):floor(log₂(1))=0 → hᵢ=3-0=3,正确
  • i=2(左子根):floor(log₂(2))=1 → hᵢ=3-1=2,正确
  • i=3(右子根):floor(log₂(3))=1 → hᵢ=3-1=2,正确
  • i=4(左左叶节点):floor(log₂(4))=2 → hᵢ=3-2=1,正确

位运算高效实现

为了避免浮点运算的精度问题,可以用位操作快速获取最高位的指数k:

  • 在Python中,利用int.bit_length()方法:k = i.bit_length() - 1(比如i=3的二进制是11,bit_length=2,k=1)
  • 在C++中,使用内置函数:k = 31 - __builtin_clz(i);(针对32位无符号整数)

对应的hᵢ计算代码示例(Python):

def get_subtree_height(i, H):
    k = i.bit_length() - 1
    return H - k

原算法的不足

你当前的循环算法需要遍历从根到目标节点的路径,时间复杂度为O(H),当H较大(比如H=30,对应百万级节点)时,性能会明显低于O(1)的位运算解法。

内容的提问来源于stack exchange,提问作者Alec Jacobson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:37:01