Bootstrap

判断一颗二叉树是否为平衡二叉树

一.判断一颗二叉树是否为平衡二叉树

题目:输入一颗二叉树的根节点,判断该二叉树是否为平衡二叉树。所谓的平衡二叉树是指以当前结点为根结点的树,左右子树的深度不得超过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;
}
;