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
}
}
答案 0 :(得分:3)
你混淆了h和n。 h是树的高度。 n显然是树中元素的数量。因此print_level采用最坏情况O($ 2 ^ i),但这也只是n。
最糟糕的情况发生在你有一个退化树,每个节点只有一个后继。在这种情况下,您有n个节点,但树的高度也是h = n。在这种情况下,每次调用print_level都需要i步,并且将i从1加到h = n得到O($ n ^ 2)。
答案 1 :(得分:2)
您始终从树t
的根开始,每次将等级提高一(i
),直到达到树h
的高度。
你说它是一棵二叉树,但你没有提到任何属性,例如平衡左右。所以我假设它可以是一个不平衡的二叉树,因此在最坏的情况下树的高度可以是h = n
,其中n
是节点的数量(这是一个完全不平衡的树,看起来像一个列表实际上)。
这意味着level_order_recursive
循环n
次。即最糟糕的情况是树有n
级别。
print_level
接收根节点和要打印的级别。它以递归方式调用直到达到级别并打印出该级别。
即I。它循环 i
次(递归调用每次减少i
)。
所以你有1 + 2 + 3 + ... + h
次迭代。自h = n
以来,您获得了1 + 2 + 3 ... + n
步骤。这是(n * (n+1))/2
(高斯和公式),它位于O(n^2)
。
如果你可以确保树是平衡的,那么你会改善最坏的情况,因为高度为h = ld(n)
,其中 ld 表示二进制对数。
答案 2 :(得分:2)
基于this或that,第3页和第4页,二分搜索算法(类似于我们的情况)的时间复杂度为T(n) = T(n/2) + c
。
除此之外,浏览左侧和右侧子树,因此下面的公式中的2T(n / 2),因为这是一个遍历算法,而不是搜索算法。
在这里,我将遵守问题并使用&#39; h&#39;而不是&#39; n&#39;。
使用递归关系,您将获得以下证明:
答案 3 :(得分:1)
在最坏的情况下,时间复杂度将是O(n ^ 2)但不能是2 ^ n,因为每个级别的时间复杂度将是 - > O(n)+ O(n-1)+ O(n-2)+ ... + O(1)最差O(n ^ 2)。