Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何以较低的复杂度计算二叉树的深度?_Algorithm_Binary Search Tree - Fatal编程技术网

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

Algorithm 如何以较低的复杂度计算二叉树的深度?,algorithm,binary-search-tree,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(he

给定二叉搜索树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) )

然而,我注意到它的复杂性呈指数级增长,因此当我们有一棵深树时,它的性能会非常差。是否有更快的算法来执行此操作?

如果将高度存储为节点对象中的字段,则可以在向树中添加节点时添加1(并在删除过程中进行减法)


这将使操作获得任何节点高度的时间保持不变,但会给添加/删除操作增加一些额外的复杂性

如果将高度存储为节点对象中的字段,则可以在向树中添加节点时添加1(并在删除过程中进行减法)


这将使操作获得任何节点高度的时间保持不变,但会给添加/删除操作增加一些额外的复杂性

这是他在回答中提到的

因此,如果您执行
(1+max(height\u left,height\u right))
,您将不得不访问每个节点,这本质上是一个O(N)操作。对于平衡树的平均情况,您将看到类似于
T(n)=2T(n/2)+Θ(1)

现在,如果您可以存储某个节点的高度,则可以将时间改进为O(1)。在这种情况下,树的高度将等于根的高度。因此,您需要对
insert(value)
方法进行修改。开始时,根的默认高度为0。要添加的节点的高度指定为0。对于在尝试添加此新节点时遇到的每个节点,如果需要,请将node.height增加1,并确保将其设置为1+max(左侧子节点高度,右侧子节点高度)。因此,height函数将简单地返回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]

这是他在回答中提到的

因此,如果您执行
(1+max(height\u left,height\u right))
,您将不得不访问每个节点,这本质上是一个O(N)操作。对于平衡树的平均情况,您将看到类似于
T(n)=2T(n/2)+Θ(1)

现在,如果您可以存储某个节点的高度,则可以将时间改进为O(1)。在这种情况下,树的高度将等于根的高度。因此,您需要对
insert(value)
方法进行修改。开始时,根的默认高度为0。要添加的节点的高度指定为0。对于在尝试添加此新节点时遇到的每个节点,如果需要,请将node.height增加1,并确保将其设置为1+max(左侧子节点高度,右侧子节点高度)。因此,height函数将简单地返回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]

树的大小随高度呈指数增长(假设是完全平衡树,则每个后续级别上的节点数是其两倍)。通常,无法避免遍历所有路径,因为您不知道哪条路径可能最高。也就是说,除非你为我们做了一些简化,否则树的大小会随着高度呈指数增长(假设是一棵完全平衡的树,则每个后续级别上的节点数是原来的两倍)。通常,无法避免遍历所有路径,因为您不知道哪条路径可能最高。也就是说,除非你为我们做了一些简化?如果你总是需要读取树中节点的高度,这听起来很聪明,但你必须维护这些值,这意味着你必须覆盖所有树操作来维护高度值。重写,不一定override@cricket_007几乎没有澄清,我试着在我的回答中解决这个问题。在添加节点时简单地添加1可能会被误解。如果以递归方式进行插入,则需要在将节点添加到树后更新高度字段。所以,
height=1+max(左边的孩子的身高,右边的孩子的身高)
应该可以做到这一点,这将是一个固定的时间操作。但是,总的来说,答案不错+1:)如果您总是需要读取树中节点的高度,那么这听起来很聪明,但您必须维护这些值,这意味着您必须覆盖所有树操作以维护高度值。不一定要重写override@cricket_007我试图在我的回答中澄清一点。在添加节点时简单地添加1可能会被误解。如果以递归方式进行插入,则需要在将节点添加到树后更新高度字段。所以,
height=1+max(左边的孩子的身高,右边的孩子的身高)
应该可以做到这一点,这将是一个固定的时间操作。但是,总的来说,答案不错+1 :)