剑指offer—关于判断二叉树是否为平衡二叉树

判断一颗二叉树是否为平衡二叉树,当这到面试题摆在我们眼前的时候,我们需要进行思考,二叉树满足平衡二叉树的条件是什么,就是对于每一个节点,它的右子树深度减去左子树的深度的绝对值必须是小于2才行。对于这个深度差,我们也叫做平衡因子。

所以,根据上面的条件,我们可以进行一种最简单的思路,就是我们首先可以对每一个节点进行遍历,然后看它的平衡因子进行比较判断,看它是不是合法。

    bool _IsAVLBinaryTree(Node *root,  int & depth)
    {
        //如果为空,往父节点返
        if (root == NULL)
        {
            depth = 0;
            return true;
        }
        //记录左节点和右节点深度
        int left = 0;
        int right = 0;
        //采取传引用的方式,下层递归进行对深度修改以后会影响上一层
        if (_IsAVLBinaryTree(root->_left, left) && _IsAVLBinaryTree(root->_right, right))
        {
            //计算平衡因子
            int pf = right - left;
            //判断平衡因子是否合法
            if (pfIsInvaild(pf))
            {
    //合法就让自身加上子树的深度,然后因为是传引用,所以当递归回到上一层的时候,上层中的right和left就是左右子树的深度
                depth = 1 + (right > left ? right : left);
                return true;
            }
        }
        return false;
    }
    //判断平衡因子是否合法
    bool pfIsInvaild(const int& pf)
    {
        return abs(pf) < 2;
    }

上述算法虽然可以实现判断一棵二叉树是否为平衡二叉树,但是我们从时间复杂度的角度思考,我们需要求深度,然后我们需要对每一个节点进行判断,所以,相当于是N*N,复杂度就是O(N^2)。在这里面我们有许多节点进行多次求取。
《剑指offer—关于判断二叉树是否为平衡二叉树》

所以我们需要一种思路让时间复杂度降下来,我们可以想,时间复杂度高的原因是因为,每次都要求出各子树深度,所以我们应该进行优化,让深度计算的同时也再进行对每个节点的判断。

所以我们提出一种思路:首先我们进行后序遍历的方式,我们先判断左节点,左节点的左右都合法我们就给它加一,然后往上一层递归返回,然后进行右节点的计算,这样最后在进行根节点的计算。

《剑指offer—关于判断二叉树是否为平衡二叉树》

    bool _IsAVLBinaryTree(Node *root,  int & depth)
    {
        //如果为空,往父节点返
        if (root == NULL)
        {
            depth = 0;
            return true;
        }
        //记录左节点和右节点深度
        int left = 0;
        int right = 0;
        //采取传引用的方式,下层递归进行对深度修改以后会影响上一层
        if (_IsAVLBinaryTree(root->_left, left) && _IsAVLBinaryTree(root->_right, right))
        {
            //计算平衡因子
            int pf = right - left;
            //判断平衡因子是否合法
            if (pfIsInvaild(pf))
            {
    //合法就让自身加上子树的深度,然后因为是传引用,所以当递归回到上一层的时候,上层中的right和left就是左右子树的深度
                depth = 1 + (right > left ? right : left);
                return true;
            }
        }
        return false;
    }
    //判断平衡因子是否合法
    bool pfIsInvaild(const int& pf)
    {
        return abs(pf) < 2;
    }

这样最终计算下来,我们相当于只对这棵树进行了一遍后序遍历,所以这个时间复杂度也就是O(N)。

代码已上传Github,链接:判断二叉树是否为AVL树

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/qq_26768741/article/details/52904313
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞