簡體   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