假设我们有顺序遍历顺序和后序遍历。例如: 有序:30 40 45 50 65 70 80 下订单:30 45 40 65 80 70 50
我知道如何根据给定的有序遍历和后序遍历来构造二进制搜索树,但我的问题是,如果给出后序遍历,BST构造的平均和最差情况时间复杂度是多少?
答案 0 :(得分:1)
在两种情况下对于天真的BST构造算法,它将是时间O(n ^ 2),因为:
在有序的情况下,算法将添加到正确的
在后序情况下,算法将添加到左侧
所以T(n)= 1 + 2 + 3 + ... n-1 = O(n ^ 2)
UPDATE_3 :但是在后序的情况下,我们可以简单地将每个下一个元素添加为根(前一个树变为左子),因此复杂度为O(n)
UPDATE :当然,数字排列的平均时间是O(n logn),但在这种情况下,这个时间是O(n ^ 2)(n是数字的数量)< / p>
UPDATE_2 :有关详细信息,请查看底部的评论。
答案 1 :(得分:0)
您可以使用以下基本原理使用O(n)中的后序遍历来构造树:
从有序的构造更加微不足道。你只需要以root身份选择中间元素并在两端递归调用它。
这是一个示例实现(在Python中),它显示了两种结构:
from collections import deque
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 visit_post_order(in_queue, limit = None):
if len(in_queue) == 0 or in_queue[-1] < limit:
return None
root = in_queue.pop()
right = visit_post_order(in_queue, max(root, limit))
left = visit_post_order(in_queue, limit)
if left is None and right is None:
return root
else:
return (left, root, right)
def visit_in_order(in_order, begin, end):
if begin==end: return None
if begin+1==end: return in_order[begin]
mid = (begin+end)/2
root = in_order[mid]
left = visit_in_order(in_order, begin, mid)
right = visit_in_order(in_order, mid+1, end)
if left is None and right is None:
return root
else:
return (left, root, right)
def from_post_order(post_order):
return visit_post_order(deque(post_order))
def from_in_order(in_order):
return visit_in_order(in_order, 0, len(in_order))
print 'digraph {'
print print_graphviz(from_post_order([0, 2, 1, 4, 3, 6, 8, 7, 5]))
#print print_graphviz(from_in_order([1, 2, 3, 4, 5, 6, 7, 8]))
print '}'
像这样跑:
python test.py | dot -Tpng | display
你会有一个很好的树输出: