使用队列遍历遍历的级别顺序的空间复杂性

时间:2013-07-14 02:16:23

标签: java data-structures binary-tree big-o space-complexity

这是级别顺序遍历的代码:

public void bfsTraveral() {
    if (root == null) {
        throw new NullPointerException("The root cannot be null.");
    }
    int currentLevelNodes = 0;
    int nextLevelNodes = 0;

    final Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    currentLevelNodes++;

    while(!queue.isEmpty()) {
        final TreeNode node = queue.poll();
        System.out.print(node.element + ",");
        currentLevelNodes--;
        if (node.left != null) { queue.add(node.left); nextLevelNodes++;}
        if (node.right != null) { queue.add(node.right); nextLevelNodes++;}
        if (currentLevelNodes == 0) {
            currentLevelNodes = nextLevelNodes;
            nextLevelNodes = 0;
            System.out.println();
        }
    }

在我看来,空间复杂度应为O(2 ^ h),其中h是树的高度,因为这是执行期间队列可达到的最大大小。在互联网上,我发现空间复杂度为O(n)。这听起来不对我。请分享您的意见。

谢谢,

2 个答案:

答案 0 :(得分:5)

如果你考虑一下,在一个有n个节点的树中,没有任何一种方法可以在任何时候让n个节点进入队列,因为没有节点会被排队两次。这给出了O(n)的直接上界。但是,这不是一个严格的限制,因为如果树是退化链表,那么内存使用将只是O(1)。

O(2 h )的上限也是正确的,但它的上限较弱。在高度为h的树中,底层中最多可以有 2 h 节点,但不能保证实际情况如此。如果树是简并链表,则高度为O(n),并且O(2 h )的界限将以指数方式过度增加内存使用量。

因此,你的界限是正确的,但O(n)是一个更好的界限。

希望这有帮助!

答案 1 :(得分:0)

O(2^h)O(n)都是正确的,前提是还要提到空间复杂度是针对最坏情况,而不是针对最佳情况。

O2^hO(n)之间的混淆在于没有提到空间复杂性是针对最坏情况还是最佳情况因为h在最坏情况和最佳情况下是不同的,并且在最佳情况下可能会误导。


最坏情况(当树平衡时) O(n)

当树平衡时,最后一级将具有最大数量的节点,即2^h。对于平衡树,h将为log n。所以O(2^h) => O(2 ^ (log n)) => O(n)

最佳情况(当树是退化链表时) O(1)

当树是退化链表时,每个级别最多具有一个节点,因此在任何时间点,队列中最多有一个节点。