判断二叉树是不是平衡

简介: 平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

 

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

例如下图中的二叉树就是一棵平衡二叉树:

 

本系列博客的第27题,我们曾介绍过如何求二叉树的深度。有了求二叉树的深度的经验之后再解决这个问题,我们很容易就能想到一个思路:在遍历树的每个结点的时候,调用函数TreeDepth得到它的左右子树的深度。如果每个结点的左右子树的深度相差都不超过1,按照定义它就是一棵平衡的二叉树

这种思路对应的代码如下:

 

int TreeDepth(SBinaryTreeNode *pTreeNode)
{
      if(!pTreeNode)
            return 0;
 
      int nLeft = TreeDepth(pTreeNode->m_pLeft);
      int nRight = TreeDepth(pTreeNode->m_pRight);
 
      return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
}

 

 

 

bool IsBalanced(BinaryTreeNode* pRoot)
{
    if(pRoot == NULL)
        return true;

    int left = TreeDepth(pRoot->m_pLeft);
    int right = TreeDepth(pRoot->m_pRight);
    int diff = left - right;
    if(diff > 1 || diff < -1)
        return false;

    return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight);
}

 

 

上面的代码固然简洁,但我们也要注意到由于一个节点会被重复遍历多次,这种思路的时间效率不高。例如在函数IsBalance中输入上图中的二叉树,首先判断根结点(值为1的结点)的左右子树是不是平衡结点。此时我们将往函数TreeDepth输入左子树根结点(值为2的结点),需要遍历结点457。接下来判断以值为2的结点为根结点的子树是不是平衡树的时候,仍然会遍历结点457。毫无疑问,重复遍历同一个结点会影响性能。接下来我们寻找不需要重复遍历的算法。

如果我们用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们已经遍历了它的左右子树。只要在遍历每个结点的时候记录它的深度(某一结点的深度等于它到叶节点的路径的长度),我们就可以一边遍历一边判断每个结点是不是平衡的。

下面是这种思路的参考代码:

 

bool IsBalanced(BinaryTreeNode* pRoot, int* pDepth)
{
    if(pRoot == NULL)
    {
        *pDepth = 0;
        return true;
    }

    int left, right;
    if(IsBalanced(pRoot->m_pLeft, &left)
        && IsBalanced(pRoot->m_pRight, &right))
    {
        int diff = left - right;
        if(diff <= 1 && diff >= -1)
        {
            *pDepth = 1 + (left > right ? left : right);
            return true;
        }
    }

    return false;
}

 

 我们只需要给上面的函数传入二叉树的根结点以及一个表示结点深度的整形变量就可以了:

bool IsBalanced(BinaryTreeNode* pRoot)
{
    int depth = 0;
    return IsBalanced(pRoot, &depth);
}

 在上面的代码中,我们用后序遍历的方式遍历整棵二叉树。在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度。当最后遍历到树的根结点的时候,也就判断了整棵二叉树是不是平衡二叉树了。

 

 

img_e00999465d1c2c1b02df587a3ec9c13d.jpg
微信公众号: 猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

目录
相关文章
|
存储 C语言 C++
问题 D: DS查找—二叉树平衡因子(不一样的新做法哦)
问题 D: DS查找—二叉树平衡因子(不一样的新做法哦)
118 0
32_将有序数组转换为平衡二叉搜索树
32_将有序数组转换为平衡二叉搜索树
|
3月前
【数据结构】翻转、平衡、对称二叉树,最大深度、判断两棵树是否相等、另一棵树的子树
【数据结构】翻转、平衡、对称二叉树,最大深度、判断两棵树是否相等、另一棵树的子树
93 0
|
5月前
|
存储 C语言 C++
D : DS查找—二叉树平衡因子
这篇文章介绍了如何计算二叉树的平衡因子,并提供了C++代码实现,用于根据二叉树的数组存储形式,计算并输出每个节点的平衡因子。
|
8月前
[leedcode]刷题有感 二叉树的深度、节点数量、与平衡二叉树2
[leedcode]刷题有感 二叉树的深度、节点数量、与平衡二叉树2
2-3-4树是如何解决二叉树中非平衡问题的?
2-3-4树是如何解决二叉树中非平衡问题的?
从前序与中序遍历序列构造二叉树(中等难度)
从前序与中序遍历序列构造二叉树(中等难度)
107 0
从前序与中序遍历序列构造二叉树(中等难度)
|
测试技术
#### [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/)
#### [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/)
|
测试技术
#### [623. 在二叉树中增加一行]
#### [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/)

热门文章

最新文章