【问题标题】:Binary tree visit: get from one leaf to another leaf二叉树访问:从一片叶子到另一片叶子
【发布时间】:2011-07-04 04:49:38
【问题描述】:

问题:我有一棵二叉树,所有叶子都有编号(从左到右,从0开始),它们之间不存在联系。

我想要一种算法,给定两个索引(2 个不同的叶子),从较大的叶子(具有较高索引的叶子)开始访问树并到达较低的叶子。

树的内部节点不包含任何有用的信息。

我应该只根据叶子索引选择路径。路径从叶子开始并在叶子上终止,当然如果我知道它的索引(通过指针数组)我可以访问叶子

树是静态的,不允许插入或删除节点。

我已经开发了一个算法来做到这一点,但它真的很糟糕......有什么想法吗?

【问题讨论】:

    标签: algorithm data-structures binary-tree


    【解决方案1】:

    一种选择是找到两个节点中最不共同的祖先,以及您应该从每个节点获取的节点序列以到达该祖先。这是算法的草图:

    1. 从每个节点开始,回到该节点的父节点,直到到达根节点。计算从每个节点到根的路径上的节点数。设第一个节点的高度为 h1,第二个节点的高度为 h2

    2. 令 h = min(h1, h2)。这是两个节点中较高节点的高度。

    3. 从每个节点开始,一直跟随节点的父指针,直到两个节点都处于高度 h。记录您在此步骤中遵循的节点。此时,两个节点的高度相同。

    4. 直到你找到一个共同的节点,从每个节点向上移动到它的父节点。最终你会击中他们共同的祖先。此时,沿着从第一个节点到这个祖先的路径,然后沿着从祖先到第二个节点的路径。

    在最坏的情况下,这需要 O(h) 时间和 O(h) 空间,其中 h 是树的高度。对于一个平衡的二叉树来说就是这个 O(lg n) 的时间和空间,已经相当不错了。

    如果您对该算法的“更硬核”版本感兴趣,请考虑研究Tarjan's Least Common Ancestors 算法,该算法具有线性预处理时间,可用于比这更快地找到最小共同祖先。

    希望这会有所帮助!

    【讨论】:

    • ok.. 我认为这是正确的解决方案,我的算法可能会更有效,但只有在所有叶子都处于相同高度时才有效。你在这里说的很有道理,而 Tarjan 是一个很好的链接!
    【解决方案2】:

    可以借助最低共同祖先计算任意两个节点之间的距离:

     Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, lca)
    

    其中 lca 是最低的共同祖先。

    请参阅this 了解有关此算法的更多帮助,并参阅video 了解如何计算 lca。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2021-01-02
      • 1970-01-01
      • 2014-05-10
      • 2019-11-21
      相关资源
      最近更新 更多