【代码随想录day16】完全二叉树的节点个数

文章讲述了如何通过不同的遍历方法(递归和非递归)来计算完全二叉树的节点数,包括前序、中序、后序、先序、中序和层序遍历。对于完全二叉树,还提到了利用满二叉树的性质进行优化,尤其是当遇到满二叉树子树时,可以直接计算节点数,无需遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目 

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

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

 

思路 

这题是标标准准得二叉树遍历得题,顺便温习一下3种递归+4种非递归方式。

# 递归前序
def solve(root):
    if not root:
        return 0
    return 1+solve(root.left)+solve(root.right)

# 递归中序
def solve(root):
    if not root:
        return 0
    return solve(root.left)+1+solve(root.right)

# 递归后序
def solve(root):
    if not root:
        return 0
    return solve(root.left)+solve(root.right)+1

# 先序遍历:直接使用一个栈遍历所有节点
def solve(root):
    if not root:
        return 0
    stack = [root]
    res = 0
    while stack:
        now = stack.pop()
        res += 1
        if now.right:
            stack.append(now.right)
        if now.left:
            stack.append(now.left)
    return res

# 中序遍历:需要借助额外指针来遍历,栈只负责存储之前的节点状态
def solve(root):
    if not root:
        return 0
    stack = []
    cur = root
    res = 0
    while cur or stack:
        if cur:
            stack.append(cur)
            cur = cur.left
        else:
            cur = stack.pop()
            res += 1
            cur = cur.right
    return res

# 后序遍历:直接使用一个栈遍历所有节点,先根右左,再逆序,不过这里求得是节点数,不需要再逆序了
def solve(root):
    if not root:
        return 0
    stack = [root]
    res = 0
    while stack:
        now = stack.pop()
        res += 1
        if now.left:
            stack.append(now.left)
        if now.right:
            stack.append(now.right)
    return res

# 层序遍历:借助队列遍历所有节点
from collections import deque
def solve(root):
    if not root:
        return 0
    q = deque([root])
    res = 0
    while q:
        now = q.popleft()
        res += 1
        if now.left:
            q.append(now.left)
        if now.right:
            q.append(now.right)
    return res

当然上面的是普通二叉树的解法。

对于完全二叉树,其中的某些子树必定为满二叉树,而满二叉树的节点个数是有公式的。

高度为h的满二叉树的节点个数是2^h-1,因此可以利用完全二叉树的这个特性进行优化。

递归整棵树,当遇到子树为满二叉树时,直接用公式返回节点个数,而不用真的遍历这个子树的所有节点。如果不为满二叉树,则继续调用countNodes方法判断当前节点的左右子树是否为满二叉树,知道找到满二叉树返回节点个数。 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        left_num = right_num = 0
        left = root.left
        right = root.right
        while left:
            left_num += 1
            left = left.left
        while right:
            right_num += 1
            right = right.right
        if left_num == right_num:
            return (2<<left_num) - 1
        return self.countNodes(root.left) + self.countNodes(root.right) + 1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小的香辛料

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

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

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

打赏作者

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

抵扣说明:

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

余额充值