Data structures 为什么递归按序遍历的空间复杂度是O(h)而不是O(n)

Data structures 为什么递归按序遍历的空间复杂度是O(h)而不是O(n),data-structures,binary-tree,traversal,inorder,Data Structures,Binary Tree,Traversal,Inorder,所以我知道递归顺序遍历的空间复杂度是O(h),而不是O(n),因为h=树的高度,n=树中的节点数 为什么呢?假设这是遍历的代码: public void inorderPrint (TreeNode root) { if (root == null) { return; } inorderPrint(root.left); System.out.println(root.data); inorderPrint(root.right);

所以我知道递归顺序遍历的空间复杂度是O(h),而不是O(n),因为h=树的高度,n=树中的节点数

为什么呢?假设这是遍历的代码:

public void inorderPrint (TreeNode root) {

    if (root == null) {
        return;
    }

    inorderPrint(root.left);
    System.out.println(root.data);
    inorderPrint(root.right);

}
我们将n个内存地址推送到调用堆栈,因此,空间复杂度应该是O(n)


我错过了什么

返回时,地址将从堆栈中删除。当从更接近根的级别进行新调用时,将重新使用此空间。因此,堆栈上同时出现的最大内存地址数就是树的高度。

IMHO,您应该将空间复杂性视为
O(n)
。在处理大O表示法中的空间和时间复杂性时,我们总是试图给出复杂性值,作为输入元素数量的函数,在这种情况下为
n

此外,如果考虑右偏斜二叉树或左偏二元的情况,那么你会发现这个<代码> o(n)< /代码>空间复杂度是合适的。请看以下右偏二叉树的情况:

  1
 / \
    2
   / \
      3
节点数,n=3

递归遍历所需的堆栈帧数=3

  1
 / \
    2
   / \
      3
     / \
        4
       / \
节点数,n=4

递归遍历所需的堆栈帧数=4

因此,您可以得出结论,在这种最坏的情况下,树结构的空间复杂度是合适的。在所有其他情况/类型的树中,所需的堆栈帧数始终小于
n
。这就是我们表达复杂性的方式。所有可能情况下占用的实际空间应始终小于或等于所描述的功能


此外,在所有情况下,递归的空间复杂度总是递归的高度/深度,因此遵循这一一般规则,按顺序遍历中最多可以有h个高度,其中h是距离根最深的节点的长度。递归的空间复杂度=O(递归树的深度)。

你不仅仅是在推——你是在弹出。因此,堆栈的某些部分被多次使用。树的高度控制在弹出前的推动量。顺便说一句——我认为您有一个输入错误,函数不应该自己调用而不是
preorderPrint
?请看下面更清楚的答案:这肯定取决于二叉树的特性。对于一般情况,是的,对于不平衡树,最坏的情况将是
O(N)
。但是,如果您知道树是平衡的(例如AVL或红黑),则可以保证树的高度最多为
Log(N)
,因此对于遍历,您的空间复杂度也将为
O(Log N)