[英]Why time complexity of following code is O(n^2)?
void level_order_recursive(struct node *t , int h) //'h' is height of my binary tree
{ //'t' is address of root node
for(int i = 0 ; i <= h ; i++)
{
print_level(t , i);
}
}
在每次调用print_level()之后,我认为递归函数被称为(2 ^ i)次。 所以2 ^ 0 + 2 ^ 1 + 2 ^ 2 .... 2 ^ h应该给出O(2 ^ n)的时间复杂度。我哪里出错了?
void print_level(struct node * t , int i)
{
if( i == 0)
cout << t -> data <<" ";
else
{
if(t -> left != NULL)
print_level(t -> left , i - 1); //recursive call
if(t -> right != NULL)
print_level(t -> right , i - 1); //recursive call
}
}
你混淆了h和n。 h是树的高度。 n显然是树中元素的数量。 因此print_level采用最坏情况O($ 2 ^ i),但这也只是n。
最糟糕的情况发生在你有一个退化树,每个节点只有一个后继。 在这种情况下,您有n个节点,但树的高度也是h = n。 在这种情况下,每次调用print_level都需要i步,并且将i从1加到h = n得到O($ n ^ 2)。
你总是从树的根部t
开始,每次( i
)将等级增加一,直到达到树h
的高度。
你说它是二叉树,但你没有提到任何属性,例如平衡左右。 所以我假设它可以是一个不平衡的二叉树,因此在最坏的情况下树的高度可以是h = n
,其中n
是节点的数量(实际上看起来像列表的完全不平衡的树)。
所以这意味着level_order_recursive
循环n
次。 即最糟糕的情况是树有n
级。
print_level
接收根节点和要打印的级别。 并且它会递归调用, 直到达到该级别并打印出该级别。
即它循环 i
倍(递归调用减小i
通过每次一个)。
所以你有1 + 2 + 3 + ... + h
次迭代。 由于h = n
你得到1 + 2 + 3 ... + n
步。 这是(n * (n+1))/2
(高斯和公式),其为O(n^2)
。
如果你可以确保树是平衡的,那么你将改善最坏的情况,因为高度将是h = ld(n)
,其中ld表示二进制对数。
在最坏的情况下,时间复杂度将是O(n ^ 2)但不能是2 ^ n,因为每个级别的时间复杂度将是 - > O(n)+ O(n-1)+ O(n-2)+ ... + O(1)最差O(n ^ 2)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.