Data structures 为什么递归按序遍历的空间复杂度是O(h)而不是O(n)
所以我知道递归顺序遍历的空间复杂度是O(h),而不是O(n),因为h=树的高度,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);
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)
。