如何在完整二叉树的最后一级找到最右边节点的位置?

时间:2016-07-08 10:38:23

标签: algorithm binary-tree

我在二叉树中遇到问题,当我遇到问题时,在完整二叉树的最后一级找到最合适的节点,这里的问题是我们必须在O(n)时间内完成是一个停止点,通过遍历所有元素,在O(n)中执行它很简单,但是有没有办法以低于O(n)的任何复杂度执行此操作,我已经通过互联网浏览了很多,而且我无法# 39;得到关于这件事的任何事情。 提前谢谢。

4 个答案:

答案 0 :(得分:1)

是的,您可以通过执行二进制搜索的变体在O(log(n)^2)中执行此操作。

这可以通过首先进入leftest元素 1 ,然后到第二个leftest元素,然后到第四个leftest元素,第8个,......直到你发现没有这样的元素。 假设您找到的最后一个元素是i,而您没有找到的第一个元素是2i

现在您可以在该范围内进行二元搜索。

这是O(log(n/2)) = O(logn)次迭代,并且由于每次迭代都在整个树上进行,所以总共O(log(n)^2)次。

(1)在这里和下面,“x leftest元素”仅指树中最深层的节点。

答案 1 :(得分:0)

由于它是一个完整的二叉树,遍历所有正确的节点直到到达叶子将采用O(logN),而不是O(N)。在常规二叉树中,它需要O(N),因为在最坏的情况下,所有节点都排成一行,但由于它是一个完整的二叉树,所以它不能

答案 2 :(得分:0)

我假设你知道节点的数量。让n这样的数字。

在完整的二叉树中,级别i的节点数量是级别i - 1的两倍。

因此,您可以在n之间迭代划分2。如果有余数,那么n是一个正确的孩子;否则,是一个左孩子。无论是否存在余数,都可以存储到序列中,最好是堆栈。

一些如:

Stack<char> s;
while (n > 1)
{
  if (n % 2 == 0)
    s.push('L');
  else
    s.push('R');
  n = n/2; // n would int so division is floor
}

while完成时,堆栈包含最右边节点的路径。

执行while的次数为log_2(n)

答案 3 :(得分:0)

这是具有时间复杂度O(lg n * lg n)和O(lg n)空间复杂度(考虑堆栈存储空间)的递归解决方案。
使用以下代码的迭代版本,可以将空间复杂度降低到O(1)。

    // helper function
    int getLeftHeight(TreeNode * node) {
      int c = 0;
      while (node) {
        c++;
        node = node -> left;
      }
      return c;
    }
    
    int getRightMostElement(TreeNode * node) {
      int h = getLeftHeight(node);

      // base case will reach when RightMostElement which is our ans is found
      if (h == 1)
        return node -> val;

      // ans lies in rightsubtree
      else if ((h - 1) == getLeftHeight(node -> right))
        return getRightMostElement(node -> right);

      // ans lies in left subtree
      else getRightMostElement(node -> left);
    }

时间复杂度推导- 在每个递归步骤中,我们都在考虑左子树还是右子树,即n / 2个元素的最大高度(lg n)函数调用,
计算高度需要lg n时间-

T(n) = T(n/2) + c1 lgn
   = T(n/4) + c1 lgn + c2 (lgn - 1)
   = ...
   = T(1) + c [lgn + (lgn-1) + (lgn-2) + ... + 1]
   = O(lgn*lgn)