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

时间:2016-12-17 18:44:23

标签: 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);

}

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

我错过了什么?

3 个答案:

答案 0 :(得分:6)

返回时,地址将从堆栈中删除。从靠近根的级别进行新呼叫时,将重新使用此空间。因此,堆栈上的最大内存地址数量是树高。

答案 1 :(得分:1)

恕我直言,您应该将空间复杂度视为import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.function.IntPredicate; import java.util.function.Supplier; import java.util.stream.IntStream; public class StreamAPI { public static void main(String[] args) { int n = 1000; Supplier<IntStream> intStreamSupplier = () -> IntStream.range(2, n).filter(new IntPredicate() { ArrayList<Integer> prev = new ArrayList<>(); @Override public boolean test(int value) { for ( int i = 0; i < prev.size(); i++ ) { if ( value % prev.get(i) == 0 ) { return false; } } prev.add(value); return true; } }); Map<Integer, IntStream> map = new HashMap<>(); for ( int i = 0; i < n; i += 100 ) { int j = i; IntStream subStream = intStreamSupplier.get().filter(new IntPredicate() { @Override public boolean test(int value) { if ( j < value && value < ( j + 100 ) ) { return true; } return false; } }); map.put(i, subStream); } for ( Map.Entry<Integer, IntStream> entry : map.entrySet() ) { Integer key = entry.getKey(); IntStream value = entry.getValue(); System.out.println("key: " + key); int[] arr = value.toArray(); for ( int i = 0; i < arr.length; i++ ) { System.out.println(arr[i]); } } } } 。在处理Big O表示法中的空间和时间复杂性时,我们总是尝试将复杂度值作为输入元素数量的函数,在这种情况下为O(n)

此外,如果您考虑右倾斜二叉树或左倾斜二进制树的情况,那么您会发现这个n空间复杂度是合适的。看看下面右倾斜二叉树的情况:

O(n)

节点数,n = 3

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

  1
 / \
    2
   / \
      3

节点数,n = 4

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

因此,您可以得出结论 1 / \ 2 / \ 3 / \ 4 / \ 在这种最糟糕的情况下是一个合适的空间复杂度w.r.t.树的结构。在所有其他情况下/树的类型所需的堆栈帧数始终小于O(n)。这就是我们表达复杂性的方式。所有可能情况所占用的实际空间应始终小于或等于所描绘的函数。

此外,在所有情况下,它始终为n。因此,将空间复杂性视为O(h) <= O(n)只是根据元素的输入数量给出了一种统一的思维方式。虽然O(n)空间复杂度同样正确,但由于@StefanHaustein在回答中提到的原因。

答案 2 :(得分:0)

递归的空间复杂度始终是递归的高度/深度,因此按照此一般规则,有序遍历最多可以有h个高度,其中h是距根最深的节点的长度。递归的空间复杂度= O(递归树的深度)。