查找二叉树直径的时间复杂度

时间:2014-01-26 03:17:28

标签: algorithm tree binary-tree time-complexity

我在这里看过各种帖子,它们计算二叉树的直径。可以找到一个这样的解决方案here(查看已接受的解决方案,而不是问题中突出显示的代码)。

我很困惑为什么代码的时间复杂度为O(n ^ 2)。我没有看到如何遍历树的节点两次(一次用于高度(通过getHeight())和一次用于直径(通过getDiameter())将是n ^ 2而不是n + n是2n。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

正如您所提到的,getHeight()的时间复杂度为O(n)。 对于每个节点,调用函数getHeight()。因此,单个节点的复杂性为O(n)。因此,整个算法(对于所有节点)的复杂性为O(n*n)

答案 1 :(得分:1)

计算每个节点的每个子树的高度应该是O(N),你只需要使用有序遍历遍历树一次。

int treeHeight(root)
{
   if(root == null) return -1;

   root->height = max(treeHeight(root->rChild),treeHeight(root->lChild)) + 1;
   return root->height;
}

这将访问每个节点1次,因此订单为O(N)。

将此与来自链接源的结果相结合,您将能够确定哪个2个节点在最差的另一次遍历之间具有最长的路径。

确实this描述了在O(N)

中执行此操作的方法

此解决方案(优化的解决方案)与引用的解决方案之间的区别在于,在将搜索大小缩小到仅1个节点(根节点)之后,每次引用的解决方案都会重新计算树高。因此,从上面来看,复杂性将是O(N +(N-1)+ ... + 1)。

总和

1 + 2 + ... + N 

等于

= N(N + 1)/2

因此,重复调用getHeight所有操作之和的复杂性将为O(N ^ 2)

为了完整起见,相反,优化后的解决方案getHeight()在预计算之后将具有复杂度O(1),因为每个节点都将该值存储为节点的数据成员。

答案 2 :(得分:0)

可以预先计算所有子树高度(使用O(n)时间),因此找到直径的总时间复杂度将为O(n)。