【问题标题】:GATE 2008: Time Complexity of Binary Search TreeGATE 2008:二叉搜索树的时间复杂度
【发布时间】:2015-08-12 04:45:12
【问题描述】:

给定 n 个元素 1,2,.........,n 上的二叉搜索树的后序遍历 P。您必须确定以 P 作为其后序遍历的唯一二叉搜索树。 最高效算法的时间复杂度是多少?

(a) theeta(logn)

(b) 西塔(n)

(c) theeta(nlogn)

(d) 以上都不是,因为树不能唯一确定

答案是(b),请说明解决方法。如果我们得到了后序遍历,我们是否需要应用sorting(O(nlogn)) 来按顺序计算?

【问题讨论】:

  • 元素是否按数字顺序添加到树中?
  • 不,我们不需要按顺序计算。我们为什么要这样做?为了想出一个算法,试着去推理为什么这棵树应该是唯一的。
  • 我们只得到了后序遍历,因为我们知道按序遍历总是按升序给出排序列表,我们需要按序遍历和后序/前序遍历,所以我认为对遍历后的顺序进行排序,我们可以按顺序排列
  • @Marichyasana 这只是提供信息
  • 我使用您的问题陈述的第一段搜索了互联网。有一个页面对此进行了解释,但使用的是预购。您是否要求对该页面进行解释,该页面是订购后的指南? http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversa/

标签: algorithm binary-tree binary-search-tree


【解决方案1】:

不,您不必对其进行排序。

在后序遍历中你可以找到一些隐藏的信息。喜欢:

  • 最后一个元素总是树根
  • 所有大于根的先前元素都是右子树的一部分。所有较小的元素都是左子树的一部分。
  • 您可以递归地应用上述规则。

这是正确的,因为您只有不同的元素。如果有重复,则遍历的树不可能是唯一的。

这是一个示例实现(在 Python 中),它显示了这一点:

from collections import deque

def visit(in_queue, limit = None):
    if len(in_queue) == 0 or in_queue[-1] < limit:
        return None
    root = in_queue.pop()
    right = visit(in_queue, max(root, limit))
    left = visit(in_queue, limit)

    if left is None and right is None:
        return root
    else:
        return (left, root, right)

def print_graphviz(tree):
    if not isinstance(tree, tuple):
        return tree
    left = print_graphviz(tree[0])
    right = print_graphviz(tree[2])

    if left is not None: print tree[1], '->', left
    if right is not None: print tree[1], '->', right
    return tree[1]

def make_tree(post_order):
    return visit(deque(post_order))

print 'digraph {'
print print_graphviz(make_tree([0, 2, 1, 4, 3, 6, 8, 7, 5]))
print '}'

像这样运行:

python test.py | dot -Tpng | display

你会得到一个漂亮的树输出:

【讨论】:

  • 这意味着如果我们有带有不同元素的后订单,我们总是可以在 O(n) 时间内创建一个 B.S.T 并且对我上面提到的问题的答案应该是 (b)。请确认。我们可以将相同的过程反向应用到 Pre-order traversal 来构造 B.S.T 吗?
  • @GamRaj 是的,它是 (b)。是的,基本原理是一样的。
【解决方案2】:

您可以取中心元素(它是该子树的根),左树将使用较小的数字构建,而右树将使用较大的数字(一切都使用递归)。 在伪代码中:

make_BST(T[]):

  1. 如果在 T 中我们的元素少于 2 个:返回包含该元素的树
  2. 否则:返回根为 T 的中心元素的树(我们将其命名为 x),左子将是 make_BST(T 中小于 x 的元素),右子将是 make_BST(T 中大于 x 的元素)

当然,您应该只记住整个 T 以及所考虑范围的左右边界。

这个算法的复杂度是 T(n) = T(n/2) + T(n/2) + O(1) 所以 T(n) = O(n) 所以复杂度和上面的帖子。

【讨论】:

    【解决方案3】:

    在post oders遍历中,根总是可以在最后一个节点找到,所以它需要o(logn)的时间复杂度。 现在,在快速排序中,以根为中心,小于根的元素将在左侧,其余的将在右侧,假设有 k 个这样的元素小于根。 所以,递推方程为,

    T(n)=T(k)+T(n-k-1)+O(logn)

    现在,在最坏的情况下设置 k=0,所以方程看起来像

    T(n)=T(n-1)+O(logn)

    通过解决它,我们得到

    T(n)=O(logn!) [O(logn)= O(log1)+O(log2)+O(log3)+...+O(logn)] 这将小于 O(logn)+O(logn)+...+O(logn)。

    所以,我们可以得到上面的 O(nlogn)。

    答案:- theta(n logn)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      相关资源
      最近更新 更多