如果二叉树的左子树和二叉树都是高度平衡的话。右子树是平衡的,左子树和右子树的高度之差小于或等于1.
我必须找出给定的二叉树是否平衡!
基于以上概念,我使用了以下代码:
bool isbalanced(struct node *root)
{
int left,right;
if(root==NULL)
return true;
else
{
left=height(root->left);
right=height(root->right);
if(abs(left-right)<=1 && isbalanced(root->right)==true && isbalanced(root->left)==true)
return true;
else
{
return false;
}
}
}
我使用单独的height()函数计算了高度:
int height(struct node *root)
{
if(root==NULL)
return 0;
int left=height(root->left);
int right=height(root->right);
if(left>right)
return 1+left;
else
return 1+right;
}
如果树平衡或不平衡,我会得到正确的解决方案。但是如果给定的树是偏斜的,那么时间复杂度将是O(n ^ 2)。
是否有方法可以更有效地完成此任务?
答案 0 :(得分:3)
将给定树视为有根树,我们可以在给定树上使用单个深度优先搜索计算所有节点的高度。拟议解决方案草图:
int isbalanced(struct node *root)
{
int left,right;
if(root==NULL)
return 0;
else
{
left=isbalanced(root->left);
right=isbalanced(root->right);
if(left==-1||right==-1||fabs(left-right)>1){
return -1; // it indicates the tree rooted at root or below is imbalanced
}else{
return max(right,left)+1;
}
}
}
如果上述函数返回-1,则树是不平衡的,否则为平衡。它不需要高度函数。
运行时:O(V + E)
请注意:代码未经过测试
答案 1 :(得分:1)
您正在两次遍历左右子树:一次获得高度,然后再次测试它们是否平衡。您可以通过使用包含高度和平衡标志的结构来消除一半的工作,将一个结构向下传递以由左子树填充,另一个向右传递。
然后,您可以在扫描右侧时使用左子树中的信息进一步改进(反之亦然)。可以使用左子树信息(使用适当的簿记 1 )在许多情况下尽早切断正确的子树搜索,在这种情况下,整个树不平衡但每个子树都是平衡的。
1 簿记详情留给读者练习