如何计算复杂度较低的二叉树的深度?

时间:2016-05-09 01:05:04

标签: algorithm binary-search-tree

给定二叉搜索树t,使用递归可以很容易地得到它的深度,如下所示:

def node_height(t):     
    if t.left.value == None and t.right.value == None:
        return 1
    else:
        height_left = t.left.node_height()
        height_right = t.right.node_height()
        return ( 1 + max(height_left,height_right) )

然而,我注意到它的复杂性呈指数级增长,因此当我们有一棵深树时,它应该表现得非常糟糕。有没有更快的算法呢?

2 个答案:

答案 0 :(得分:3)

如果将高度存储为Node对象中的字段,则可以在向树中添加节点时添加1(并在删除期间减去)。

这样可以使操作保持恒定的时间来获取任何节点的高度,但它会在添加/删除操作中增加一些额外的复杂性。

答案 1 :(得分:2)

这种延伸来自他在答案中提到的@cricket_007

因此,如果您执行( 1 + max(height_left,height_right) ),则最终必须访问每个节点,这实际上是一个O(N)操作。对于具有平衡树的平均情况,您会看到类似T(n) = 2T(n/2) + Θ(1)的内容。

现在,如果您可以存储某个节点的高度,则可以将其改进为O(1)的时间。在这种情况下,树的高度将等于根的高度。因此,您需要进行的修改将是您的insert(value)方法。在开始时,根的默认高度为0.要添加的节点的高度为0.对于尝试添加此新节点时遇到的每个节点,如果需要,请将node.height增加1,并确保它被设置为1 + max(左孩子的身高,右孩子的身高)。因此,高度函数将简单地返回node.height,因此允许恒定时间。插入物的时间复杂度也不会改变;我们只需要一些额外的空间来存储n整数值,其中n是节点数。

以下内容旨在让我们了解我想说的内容。

          5 [0]

- insert 2 [increase height of root by 1]

          5 [1]
         / 
        /   
   [0] 2 

- insert 1 [increase height of node 2 by 1, increase height of node 5 by 1]

          5 [2]
         / 
        /   
   [1] 2    
      / 
     /   
[0] 1  

- insert 3 [new height of node 2 = 1 + max(height of node 1, height of node 3) 
                                 = 1 + 0 = 1; height of node 5 also does not change]

          5 [2]
         / 
        /   
   [1] 2     
      / \
     /   \
[0] 1     3 [0]

- insert 6 [new height of node 5 = 1 + max(height of node 2, height of node 6) 
                                 = 1 + 1 = 2]

          5 [2]
         / \
        /   \
   [1] 2     6 [0]
      / \
     /   \
[0] 1     3 [0]