010.完全二叉树的节点个数

题目链接:力扣

大概思路:

完全二叉树思路:(利用完全二叉树性质来完成题目)

先明确完全二叉树的定义:

1.除底层节点可能不是满的,底层节点以上的节点都是满的。

2.底层节点不是满的情况下,节点要都靠在最左边,不能有断裂。


然后了解完全二叉树有且只有两种情况,并利用这个特性来计算完全二叉树的节点数量

1.满二叉树(可以用2^树深度 - 1 来计算,注意这里根节点深度为1(后面看到代码的解释就知道了))

2.底层的叶子节点没有满(这个情况继续向下递归,一定会遇见满二叉树,如下图)

 思路就是一直向下递归,遇见满二叉树就计算出结果返回,因为就算是非满二叉树,也可以继续递归,直到找到满二叉树为止(一定会找到),像上图那个只有一个节点的满二叉树,算完值返回后,它的上一个节点也会变成一个满二叉树了,计算完就继续返回。

-

问题来了,在代码里如何判断它是满二叉树?(编译器没有人的眼睛,不能直接看出来)

可以判断节点左右子树的深度,按照完全二叉树的定义,相同就代表是满二叉树,不相同就代表是非满二叉树。(注意下图不是,因为有断裂)

所以大概思路就是:

“二叉树后序遍历的基础上” + “加上是不是满二叉树判断,判断是“就”计算并返回上层递归” + “最后返回最终值就行” 。

代码思路:(递归三步曲)

1.确定函数参数和返回类型:

参数就是传入树的根节点,返回就返回以该节点为根节点二叉树的节点数量,所以返回值为int类型。

int countNodes(TreeNode* root){}

2.终止条件:

如果为空节点的话,就返回0,表示节点数为0。

if (cur == NULL) return 0;

判断下面的节点是不是满二叉树,是就计算并返回

大概意思:双指针指向节点的左右子树,然后两指针不断向左和右遍历,直到本身变成空节点,然后结束循环,得到左右子树深度,接下来做判断,深度相等,是满二叉树,返回计算的值。

if (root == nullptr) return 0; 
// 开始根据做深度和有深度是否相同来判断该子树是不是满二叉树
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) {  // 求左子树深度
    left = left->left;
    leftDepth++;
}
while (right) { // 求右子树深度
    right = right->right;
    rightDepth++;
}
if (leftDepth == rightDepth) {
    return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,返回满足满二叉树的子树节点数量
}

3.单层循环逻辑:

int leftTreeNum = countNodes(root->left);       // 左
int rightTreeNum = countNodes(root->right);     // 右
int result = leftTreeNum + rightTreeNum + 1;    // 中
return result;

4.总代码

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == nullptr) return 0;

        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
        while (left) {  // 求左子树深度
            left = left->left;
            leftDepth++;
        }
        while (right) { // 求右子树深度
            right = right->right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
        }

        int leftTreeNum = countNodes(root->left);       // 左
        int rightTreeNum = countNodes(root->right);     // 右
        int result = leftTreeNum + rightTreeNum + 1;    // 中
        return result;

    }
};

个人想法:

h1和h2标题之间字体大小差距太小了,做笔记不好看,嗯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用二叉链表存储结构建立一棵二叉树并完成对应功能的Python代码: ```python class Node: def __init__(self, data): self.data = data self.left = None self.right = None class BinaryTree: def __init__(self, data_list): self.root = None self.node_list = [] for data in data_list: node = Node(data) self.node_list.append(node) for i in range(len(data_list)//2-1): self.node_list[i].left = self.node_list[i*2+1] self.node_list[i].right = self.node_list[i*2+2] last_parent_index = len(data_list)//2-1 self.node_list[last_parent_index].left = self.node_list[last_parent_index*2+1] if len(data_list) % 2 == 1: self.node_list[last_parent_index].right = self.node_list[last_parent_index*2+2] def pre_order(self, root): if root: print(root.data, end=' ') self.pre_order(root.left) self.pre_order(root.right) def in_order(self, root): if root: self.in_order(root.left) print(root.data, end=' ') self.in_order(root.right) def post_order(self, root): if root: self.post_order(root.left) self.post_order(root.right) print(root.data, end=' ') def get_depth(self, root): if root is None: return 0 else: left_depth = self.get_depth(root.left) right_depth = self.get_depth(root.right) return max(left_depth, right_depth) + 1 def get_leaf_num(self, root): if not root: return 0 elif not root.left and not root.right: return 1 else: return self.get_leaf_num(root.left) + self.get_leaf_num(root.right) if __name__ == '__main__': data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] binary_tree = BinaryTree(data) print("先序遍历:", end='') binary_tree.pre_order(binary_tree.root) print("\n中序遍历:", end='') binary_tree.in_order(binary_tree.root) print("\n后序遍历:", end='') binary_tree.post_order(binary_tree.root) print("\n二叉树深度:", binary_tree.get_depth(binary_tree.root)) print("二叉树叶子结点个数:", binary_tree.get_leaf_num(binary_tree.root)) ``` 上面的代码中,我们用Node类来表示二叉树的节点,用BinaryTree类来表示二叉树。在BinaryTree类的初始化方法中,我们通过给定的数据列表data_list构建了一个包含所有节点的列表node_list,并且根据完全二叉树的性质建立起了二叉树的结构。在先序、中序、后序遍历的方法中,我们分别按照对应的遍历顺序输出节点的data值即可。在求二叉树深度的方法中,我们递归地计算左右子树的深度,取较大值并加1,即为整棵树的深度。在求二叉树叶子结点个数的方法中,我们递归地判断节点是否为叶子节点,如果是则返回1,否则分别递归计算左右子树的叶子结点个数并相加。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值