222 完全二叉树的节点个数(递归、二分)

265 篇文章 5 订阅
41 篇文章 0 订阅

1. 问题描述:

给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点

示例:

输入: 
    1
   /  \
  2   3
 /  \   /
4  5 6

输出: 6

2. 思路分析:

① 计算二叉树的节点的数目,可以直接写一个递归的方法进行计算,因为要求返回值,所以可以写一个有返回值的递归进行求解,我们可以计算出左右子树节点的数目然后加上1表示当前节点的子树的数目,然后将其返回即可,对于每一个节点都是这样进行操作,所以最终会返回整棵树的节点的数目。

② 除了①中的思路我们其实还可以进一步优化,我们需要找到完全二叉树中完全二叉子树与满二叉子树的一个分界点,我们知道如果一棵树为满二叉树那么可以直接使用公式计算,所以我们可以这样解决,先判断当前的二叉树是否是满二叉树,如果是那么直接使用公式计算即可,如果不是那么分别递归左右子树即可,左右子树又可以执行同样的操作。可以通过一直往左边的节点与一直往右边的节点的层数是否相等来判断是否是当前的根节点的子树是否是满二叉树,这样就可以不用遍历所有的节点,可以减少时间复杂度。

3. 代码如下:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


class Solution:
    def dfs(self, root: TreeNode):
        if root is None: return 0
        # 递归左右子树加上根节点的数目
        return 1 + self.dfs(root.left) + self.dfs(root.right)

    def countNodes(self, root: TreeNode) -> int:
        return self.dfs(root)


if __name__ == '__main__':
    root = TreeNode(1)
    l = TreeNode(2)
    r = TreeNode(3)
    ll = TreeNode(4)
    lr = TreeNode(5)
    rl = TreeNode(6)
    root.left = l
    root.right = r
    l.left = ll
    l.right = lr
    r.left = rl
    print(Solution().countNodes(root))

python代码:

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


class Solution:
    # 实际上是二分的思路
    def countNodes(self, root: TreeNode) -> int:
        if not root: return 0
        x, y = 1, 1
        l, r = root.left, root.right
         # 判断当前是否是满二叉树
        while l:
            x += 1
            l = l.left
        while r:
            y += 1
            r = r.right
        if x == y:
            return (1 << x) - 1
        return 1 + self.countNodes(root.left) + self.countNodes(root.right)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值