完全二叉树的节点个数(leetcode222. 完全二叉树的节点个数)

完全二叉树的节点个数

222. 完全二叉树的节点个数

如果只是求一个二叉树的节点个数,是相对来说比较容易的,无论是递归法还是迭代法,都可以很容易的想出思路,此处我直接贴出代码

普通二叉树

递归

class Solution {
    // 通用递归解法
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

迭代

class Solution {
    // 迭代法
    public int countNodes(TreeNode root) {
        if (root == null) return 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int result = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size -- > 0) {
                TreeNode cur = queue.poll();
                result++;
                if (cur.left != null) queue.offer(cur.left);
                if (cur.right != null) queue.offer(cur.right);
            }
        }
        return result;
    }
}

完全二叉树

既然本题要求的是完全二叉树,所以就要利用完全二叉树的特点。

完全二叉树我们都不陌生,按照通俗的话来讲,就是:满二叉树 或者 只缺右下角节点的满二叉树

所以我们就分两种情况来判断

  1. 满二叉树的情况

满二叉树的节点个数只和树的层高(深度)有关:2的n次方-1(如图所示,节点个数为2的4次方-1 = 15)

  1. 只缺右下角节点的满二叉树

可以把这种情况的的完全二叉树拆分成两个完全二叉树,再对两个二叉树分别做判断,如果不是满二叉树就继续拆,一直拆到是满二叉树为止

以此完全二叉树为例,根节点的左子树为满二叉树,可以直接得出节点个数,右子树为完全二叉树,可以再将右子树作为根节点进一步进行细分(递归)

我们发现左子树为满二叉树,右子树为完全二叉树。以此类推。

那我们怎么判断该树是否是完全二叉树还是满二叉树呢

可以用左右子树的深度来判断

但是左右子树的深度不用像之前递归一样把每个节点都遍历一遍。依据完全二叉树的性质,我们只用看整个树的最左下角节点和右下角节点的深度就可以了。

以上图只缺右下角节点的满二叉树为例

其左下角的节点为8,右下角的节点为7。

其深度用简单的循环就可以求出

while(left != null) {
    left = left.left;
    leftDepth++;
}

同理求出最右下角节点。

只用比较这两个节点的深度是否相等即可:leftDepth == rightDepth

代码

class Solution {
    public int countNodes(TreeNode root) {
        //利用完全二叉树的特点
        if (root == null) return 0;
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftDepth = 0;//leftDepth+1表示当前的层数,方便后面计算
        int rightDepth = 0;
        while (left != null) {
            left = left.left;
            leftDepth++;
        }
        while (right != null) {
            right = right.right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
//            return (int) (Math.pow(2,leftDepth+1) - 1);
            return (2 << leftDepth) - 1;//前面让leftDepth从0开始就是为了方便这里的计算,本行和上一行等价
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值