统计完全二叉树的节点数

统计完全二叉树的节点数

题目

给定一棵完全二叉树,求节点个数,要求时间复杂度小于O(n)

思路

A
B
C
D
E
F
G
H
I
J
K
L

如图根为A的完全二叉树,先求出A的极左节点H的层数4,
然后找到A的右孩子C,然后找到C的极左节点L,L的层数等于整棵树的层数4,
所以可以肯定A的左子树必定是一棵满二叉树,节点数2**(4-1) - 1 = 7,加上A有8个节点,
而A的右子树节点数可以递归去求解。

A
B
C
D
E
F
G
H
I
J

如果A的右孩子C的极左节点F没有到达最后一层,则说明A的右子树必定是满二叉树,节点数为2**(3 - 1) - 1,连上根节点,共4个节点,而左子树可以递归求解。

实现

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


def node_num_of_cbt(root):
    def most_left_level(node, level):
        while node:
            level += 1
            node = node.left
        return level - 1

    def node_num(node, level):
        if level == height:
            return 1

        if most_left_level(node.right, level+1) == height:
            return (1 << (height - level)) + node_num(node.right, level+1)
        else:
            return (1 << (height - level - 1)) + node_num(node.left, level+1)

    if root is None:
        return 0

    height = most_left_level(root, 0)
    return node_num(root, 0)

测试

import unittest
import node_num_of_complete_binary_tree as cbt
import random


class NodeNumOfCompleteBinaryTreeCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def make_cbt(self, count):
        if count == 0:
            return None

        nodes = [cbt.TreeNode(i) for i in range(count)]
        for i in range(count):
            left = 2*i + 1
            right = 2*i + 2
            if left < count:
                nodes[i].left = nodes[left]
            if right < count:
                nodes[i].right = nodes[right]

        return nodes[0]

    def test_sequence(self):
        for i in range(10):
            root = self.make_cbt(i)
            cnt = cbt.node_num_of_cbt(root)
            self.assertTrue(cnt == i)

    def test_random(self):
        for i in range(10):
            count = random.randint(0, 100)
            root = self.make_cbt(count)
            cnt = cbt.node_num_of_cbt(root)
            self.assertTrue(cnt == count)

结果

➜  24_node_nuim_of_complete_binary_tree python -m unittest test_node_num_of_complete_binary_tree
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值