面试问:二叉树顺序遍历

时间:2014-02-12 08:38:56

标签: java algorithm tree binary-tree graph-algorithm

我在接受采访时被问到这个问题。

问题: 二叉树,我们也会给出相应子树的高度。然后我们必须按顺序在特定位置找到一个元素。

例如:树结构为: D (根节点)[subtree-size = 6] - > B,F (D的子节点)[子树大小= 2] - > A,C,E,G (叶节点)[subtree-size = 0]。

总共有3个级别: 0级:D; 等级1 :B,F; 等级2 :A,C,E,G

我们必须按顺序计算特定订单/位置的节点,比如说p。如果p = 2,那么节点将是B( inorder遍历)。

我的解决方案:我建议我们需要进行一次intra遍历(通过BFS / DFS)然后我们可以给出第i个顺序节点,时间复杂度为O(n)

现在我被问到我可以根据子树大小信息改进解决方案。但我无法想出任何可以减少时间复杂度的子树大小的方法。

子树大小信息可以减少时间复杂度吗?如果是,请分享算法/伪代码。

1 个答案:

答案 0 :(得分:5)

如果我们想在inorder遍历中的第i个位置找到元素:

  • 如果左子树有完全i-1个节点,我们知道我们正在寻找根。
  • 我们知道如果左子树有i个或更多节点,它将在左子树中。
  • 我们知道如果左子树的节点少于i-1,它将在正确的子树中。
  • 我们可以通过适当更新i来递归重复此操作。更具体地说,我们需要通过左子树的大小加上一个i减少每当我们去右子树,作为树的序遍历将在原有的序遍历该位置开始。当转到左子树时,我们不需要更改i,因为该子树的inorder遍历将从原始inorder遍历的起始位置开始。

因此,在伪代码中,我们可以执行以下操作:

currentNode = root
while true
  if getSubtreeCount(currentNode.left) == i-1
    return currentNode
  else if getSubtreeCount(currentNode.left) < i-1
    currentNode = currentNode.left
  else
    currentNode = currentNode.right
    i -= getSubtreeCount(currentNode.left) + 1

这将为我们提供O(treeHeight)的运行时间。

示例:

假设我们有一棵树:

     D
   /   \
  B     F
 / \   / \
A   C E   G

假设我们正在寻找inorder遍历中的第二个位置。我们从D开始。我们看到左子树有3个节点,所以我们知道第二个位置在左子树中。看B,我们看到左子树有1个节点,所以我们知道B位于第2位。

假设我们正在寻找inorder遍历中的第5个位置。我们从D开始。我们看到左子树有3个节点,所以我们知道第6个位置在右子树中。看看F,我们现在寻找第一个位置,因为在我们到达以F为根的子树之前,在顺序遍历中有4个节点。我们看到左子树有1个节点,所以我们知道子树包含第一个位置的节点。看看E,我们看到左子树有0个节点,所以我们知道E在这个子树的第一个位置,即我们正在寻找的节点。