二叉树直径 - 算法复杂度

时间:2015-04-13 18:56:40

标签: algorithm binary-tree time-complexity

another question中关于找到计算二叉树直径的算法,提供以下代码作为问题的可能答案。

public static int getDiameter(BinaryTreeNode root) {        
    if (root == null)
        return 0;

    int rootDiameter = getHeight(root.getLeft()) + getHeight(root.getRight()) + 1;
    int leftDiameter = getDiameter(root.getLeft());
    int rightDiameter = getDiameter(root.getRight());

    return Math.max(rootDiameter, Math.max(leftDiameter, rightDiameter));
}

public static int getHeight(BinaryTreeNode root) {
    if (root == null)
        return 0;

    return Math.max(getHeight(root.getLeft()), getHeight(root.getRight())) + 1;
}

在评论部分,据说上述代码的时间复杂度为O(n ^ 2)。在给定getDiameter函数的调用时,将为左右子树调用getHeightgetDiameter函数。

让我们考虑二叉树的平均情况。高度可以在Θ(n)时间计算(对于最坏情况也是如此)。那么我们如何计算getDiameter函数的时间复杂度?

我的两个理论

  1. Τ(n)= 4T(n / 2)+Θ(1)=Θ(n ^ 2),考虑高度计算 (相同?)子问题。

  2. T(n)= 2T(n / 2)+ n +Θ(1)=Θ(nlogn),n = 2 * n / 2用于高度计算?

  3. 感谢您的时间和精力!

1 个答案:

答案 0 :(得分:2)

有一点困惑在于您认为二叉树是平衡的。实际上,它可以是一条线。在这种情况下,我们需要从根到叶子的n操作来查找从根的子项到叶子的高度n - 1,依此类推。这使得O(n^2)操作可以单独找到所有节点的高度。

如果在找到直径之前独立计算每个节点的高度,则可以优化算法。然后我们会花费O(n)时间来寻找所有高度。然后找到直径的复杂性将是以下类型:

  

T(n)= T(a)+ T(n-1-a)+ 1

其中a是左子树的大小。这种关系也会给出寻找直径的线性时间。所以总时间是线性的。