繁体   English   中英

打印 BST 的所有路径的时间复杂度是多少

[英]What is the time complexity of printing all paths of a BST

我有这段代码,它与本网站上具有相同问题的其他一些代码略有不同:

public void printAllRootToLeafPaths(Node node,ArrayList path) {
    if(node==null){
        return;
    }
    path.add(node.data);

    if(node.left==null && node.right==null)
    {
        System.out.println(path);
        return;
    }
    else {
        printAllRootToLeafPaths(node.left, new ArrayList(path));
        printAllRootToLeafPaths(node.right,new ArrayList(path));
    }      
}

有人可以解释为什么最好的情况是 O(nlogn) 吗? 最坏的情况,树分解成一个链表,数组被复制 1+2+3+...+n-1+n 次,相当于 n^2,所以时间复杂度是 O(n^2) .
沿着路径中的每个节点复制最佳情况数组。 所以复制它看起来像 1+2+3+...+logn。 N/2 次。 那么,如果 1+2+3+...+n-1+n 是 n^2,为什么总和 (logn)^2 不是呢? 制作最佳情况 O(n(logn)^2)?

是的,所有的复制都需要考虑在内。

这些副本不是必需的; 编写以下函数很容易:

  • 使用(单个)链表代替 ArrayList,或
  • 使用单个 ArrayList,在不再需要以前的路径时覆盖它们。

对于非复制算法,算法的成本是打印路径的成本,它是从根到叶的所有路径长度的总和。 在每次调用时复制数组,使成本成为从根到每个节点的路径之和,而不是每个叶子。 (数组被复制两次的事实实际上与复杂度分析无关;它只是意味着乘以一个常数因子,可以忽略。)

使用非复制算法,最好的情况是一棵线性树,每个节点只有一个孩子。 那么只有一个路径长度为N的叶子,所以总成本是 O( N )。 但如果你在每个节点上复制,那是最坏的输入; 节点路径长度是连续整数,节点路径长度之和是二次的。

对于您的算法,最好的情况是完全平衡的完全占用树。 在完全占用的树中,叶子节点比非叶子节点多一个; 换句话说,大约一半的节点是叶子。 在完美平衡的树中,每个节点都可以在最多 log N步内从根到达。 所以到每个节点的路径长度之和是 O( N log N )。 (有些节点更接近,但是对于计算大 O,我们可以忽略这个事实。即使我们将其考虑在内,我们也会发现它不会改变渐近行为,因为每个深度的节点数每个连续级别的级别加倍。)因为一半的节点是叶子,所以这个输入的成本是 O( N log N ) 与非复制算法也是如此。

两种算法都表现出最坏情况的二次复杂度。 我们已经看到了复制算法的最坏情况输入:只有一个叶子的线性树。 对于非复制算法,我们使用非常相似的东西:由左链接主干组成的树,其中每个右链接都是叶子:

                         root
                          /\
                         /  \
                        /\   7
                       /  \
                      /\   6
                     /  \
                    /\   5
                   /  \
                  /\   4
                 /  \
                /\   3
               /  \
               1  2

由于那棵树被完全占用,它的一半节点是叶子,并且它们的距离连续增加,所以这又是二次的(尽管常数乘数更小。)

我认为您错过了将整个数组复制到新数组的时间复杂度。


在根节点: one element is added, but 2 new arrays are created

在根节点的左子节点: one element is added, but 2 new arrays are created with 2 elements

. . .

最后只有一层: one element is added, but 2 new arrays are created of size log n to base 2.

在最后一级:添加一个元素,并打印 log n 个元素。


因此,在每个节点处,有一个将元素添加到列表的操作,以及一个打印或复制大小列表 (log h) 的操作 - 其中 h 是树中节点的高度。

由于我们只遍历所有元素一次,因此操作总数为: n additions + Sum (log h1 + log h2 + log h3 +.... log hn)

其中 h1, h2, h3...hn 是每个节点的高度。

大约是n + O(n log n) ~ O(n log n)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM