一.判断一颗二叉树是否为平衡二叉树
题目:输入一颗二叉树的根节点,判断该二叉树是否为平衡二叉树。所谓的平衡二叉树是指以当前结点为根结点的树,左右子树的深度不得超过1。
例如:
解决思路一:按照前序遍历的路线判断。
- 1.判断以根结点的树是否为二叉平衡树。求出左右子树的高度,判断它们的高度差是否超过了1。
- 2.递归判断根的左子树是否为平衡二叉树
- 3.递归判断根的右子树是否为平衡二叉树
注意:空树也是平衡二叉树
代码实现:
//二叉树的高度(比较左右子树那个高,高的加1既为二叉树的高度)
int BinaryTreeHigh(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int ret1 = BinaryTreeHigh(root->_left);
int ret2 = BinaryTreeHigh(root->_right);
//二叉树的高度为左子树和右子树中高的那个高度加1
return ret1 > ret2 ? ret1 + 1 : ret2 + 1;
}
//判断树是否为平衡二叉树(1:是 0:不是)
int IsBlancedTree_R(BTNode* root)
{
//空树是平衡二叉树
//平衡二叉树是指以当前结点为根的左右子树高度不得超过1
if (root == NULL)
return 1;
//右子树深度
int right = BinaryTreeHigh(root->_left);
//左子树深度
int left = BinaryTreeHigh(root->_right);
int gap = right - left;
//深度超过1不是
if (gap > 1 || gap < -1)
return 0;
//递归判断子树
return IsBlancedTree_R(root->_left) && IsBlancedTree_R(root->_right);
}
对于上边的代码,效率会很低
,因为这种方法存在着许多重复的计算
。以上图的例子分析,从12
开始判断,用BinaryTreeHigh
函数求深度时,要遍历35、9,
而在判断以35
位根的树是否为平衡二叉树时也要遍历9
。因此,这种方法存在着许多重复的计算。那么我们怎么能让它们不重复呢?
解决思路二:按照后序遍历的路线判断
- 1.首先,判断它的左子树是否为平衡二叉树
- 2.然后在判断它的右子树是否为平衡二叉树
- 3.判断它们是否为平衡二叉树的同时,记录它们的左右子树的深度
- 4.最后在判断以这个结点为根的树是否为平衡二叉树
代码实现:
//判断树是否为平衡二叉树(1:是 0:不是)
//优化版本(不用遍历重复的结点)
int IsBlancedTree_op(BTNode* root, int *pdepth)
{
if (root == NULL)
{
*pdepth = 0;
return 1;
}
//按照后序遍历去判断,先判断左右子树,然后记录以当前结点为根树的深度
int left, right;
if (IsBlancedTree_op(root->_left, &left) && IsBlancedTree_op(root->_right, &right))
{
int gap = right - left;
if (gap <= 1 && gap >= -1)
{
*pdepth = left>right ? left + 1 : right + 1;
return 1;
}
}
return 0;
}