如何利用满二叉树的特性计算完全二叉树的节点个数!

大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。

这期给大家出一篇二叉树算法题,如何利用满二叉树的特性计算完全二叉树的节点数,对于满二叉树和完全二叉树还不熟悉的读者可以看看我之前写过的一文读懂二叉树去了解下。

满二叉树的左右节点深度一定是相等的,完全二叉树的最底层的节点数一定是连续的,所以利用这个特性,计算完全二叉树的节点数。

进阶之路!!!

遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?

利用满二叉树的特性

满二叉树的节点数:2^n - 1 (2的n次方 - 1)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
 // 力扣的#222号题目
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
       // 完全二叉树  递归写出来 利用完全二叉树的特性
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftNum = 0;
        int rightNum = 0;

        // 计算左右是不是满二叉树,如果是,用满二叉树的特性直接计算:2^n - 1
        while(left != null) {
            left = left.left;
            leftNum++;
        }

        while(right != null) {
            right = right.right;
            rightNum++;
        }

        if(rightNum == leftNum) { // 左右深度相等,是一个满二叉树
            // 计算出满二叉树的节点数返回给上面的节点
            return (2<<leftNum) - 1; // 这里用的位运算:2 << n == 2的n + 1 次方,这里n是从0开始++的
        }
        int result = 0;
        int le = countNodes(root.left); // 左
        int ri = countNodes(root.right); // 右
        result = le + ri + 1; // 中
         return result;
    }
}

广度优先搜索的层序遍历方法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }

        // 层序遍历试一试
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);

        int tem = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();
            tem = tem + size;
            
            while(size-- > 0) {
                TreeNode node = queue.poll();
                if(node.left != null) {
                    queue.offer(node.left);
                }
                if(node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return tem;
    }
}

后序遍历的递归(没有利用满二叉树的特性的普通递归)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
       // 递归
       int result = 0;
       int left = countNodes(root.left); // 左
       int right = countNodes(root.right); // 右
       result = left + right + 1; // 中
       return result;

    }
}

最后

一定要理解,知其然知其所以然!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值