算法_二叉树_完全二叉树的节点个数

完全二叉树的节点个数

leetcode链接

1.三种解法

迭代法–层序遍历

直接层序遍历遍历所有节点,然后统计个数即可。
代码如下:

def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        queue = []
        result = []
        if not root:
            return 0

        queue.append(root)

        while queue:
            size = len(queue)
            for i in range(size):
                node = queue.pop(0)
                result.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        
        return len(result)

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( n ) O(n) O(n)

递归法–后序遍历

使用后序遍历的逻辑(左右中),代码如下:

def countNodes(root):
	if not root:
		return 0
	
	leftchild_num = countNodes(root.left) # 左
	rightchild_num = countNodes(root.right) # 右
	return leftchild_num+rightchild_num+1 # 中

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( l o g 2 n ) O(log_2n) O(log2n)

递归法–完全二叉树性质

如果我们想求一棵完全二叉树的节点数目,利用完全二叉树的性质,他的节点个数应该为1~ 2 h − 1 2^h-1 2h1,h为树的深度。最大值在该树是满二叉树时取得。

所以对于满二叉树,我们是有计算公式的,所以我们要利用这个性质,用递归的方法,策略如下:

  1. 如果某个节点是满二叉树的根节点,那么我可以直接用公式计算这棵树的节点个数
  2. 如果某个节点不是满二叉树的根节点,那么我们就来探测他的左子树和右子树是不是满二叉树的根节点。
    (1)如果是则用公式计算出来,然后原树的节点个数就是左子树的节点数+右子树的节点数+1.
    (2)如果不是则在探测左子树的左子树和右子树右子树的左子树和右子树是不是满二叉树。

判断满二叉树的方式就是,计算出从该节点一直向左的深度一直向右的深度是不是相等。

这样以来我们就能看出重复操作了,所以就可以这样写代码:

def countNodes(self, root: TreeNode) -> int:
	if not root:
	    return 0
	    
	left = root.left
	right = root.right
	
	leftHeight = 0 #这里初始为0是有目的的,为了下面求指数方便
	rightHeight = 0
	
	while left: #求左子树深度
	    left = left.left
	    leftHeight += 1
	    
	while right: #求右子树深度
	    right = right.right
	    rightHeight += 1
	
	# 如果是满二叉树
	if leftHeight == rightHeight:
	    return (2 << leftHeight) - 1 #注意(2<<1) 相当于2^2,所以leftHeight初始为0
	    
	# 如果不是满二叉树
	return self.countNodes(root.left) + self.countNodes(root.right) + 1

2.总结

注意二叉树和完全二叉树的一些性质:

  1. 在二叉树上的第 i 层上至多有 2 i − 1 2^{i-1} 2i1 个节点(i>=1)
  2. 深度为 k 的二叉树至多有 2 k − 1 2^k-1 2k1 个节点(k>=1)
  3. 具有n个节点的完全二叉树的深度为 └ l o g 2 n ┘ └log2n┘ log2n+ 1
  4. 如果对一颗有n个节点的完全二叉树(其深度为 └ l o g 2 n ┘ + 1 └log2n┘+1 log2n+1)的节点按层序编号,对于任意节点i有:

如果i=1,则节点i是二叉树的根节点,无双亲;
如果i>1,则其双亲节点是 └ i / 2 ┘ └i/2┘ i/2
如果2i>n,则节点 i 无左孩子;否则其左孩子就是 2i
如果2i+1>n,则节点 i 无有右孩子;否则其右孩子就是 2i+1

  1. n0:树中度为0的节点的总数
    n1:树中度为1的节点的总数
    n2:树中度为2的节点的总数
    n:总结点数

n0 = n2+1
n = n0 + n1 + n2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值