求完全二叉树的节点个数

240 阅读2分钟

题目描述

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

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

思路

  • 该题可以直接用后序遍历求节点即可
  • 除了直接求高度,还可以利用满二叉树的特性,一颗满二叉树的节点=2^k-1(k:高度),重点就在如果判断一个树是满二叉树。本题给的是一个完全二叉树,因此只要满足节点左子树左侧高度==右子树右侧高度,就能保证该树是一颗满二叉树。

代码

后序遍历求节点数

 function countNodes(root: TreeNode | null): number {
     if(root==null) return 0;
     let leftNumber=countNodes(root.left);
     let rightNumber=countNodes(root.right);
     return leftNumber+rightNumber+1;
 }

image.png

利用满二叉树的特点求节点个数*(递归)

  1. 传入的参数:node (当前节点)
  2. 终止条件:
  • 当前节点为null
  • 当前子树为满二叉树,返回当前子树的节点数

难点:如何判断当前子树为满二叉树呢?

image.png

答案是:左子树左侧高度==右子树右侧高度

20220829163554.png

20220829163709.png

20220829163811.png

function countNodes(root: TreeNode | null): number {
    if(root==null) return 0;
    /**
        求左子树左侧,右子树右侧的高度,如果高度相同,说明该树是满二叉树
     */
    let left=root.left; //遍历节点左侧的指针
    let right=root.right;// 遍历节点右侧的指针
    //左右两侧高度
    let leftDepth=1,rightDepth=1;
    while(left){
        left=left.left;
        leftDepth++;
    }

    while(right){
        right=right.right;
        rightDepth++;
    }

    //满二叉树的节点数为:2^k-1(k:树的高度)
    if(leftDepth===rightDepth) return Math.pow(2,leftDepth)-1 ;

    /**
        不是满二叉树,继续递归判断子树是否是满二叉树。
        不用担心死循环,因为遍历到叶子节点,叶子节点本身就算是满二叉树。
     */
    let leftNumber=countNodes(root.left);
    let rightNumber=countNodes(root.right);

    //返回节点总数
    return leftNumber+rightNumber+1;
};

image.png

总结

本题直接使用后序遍历会很简单,但我还是想学习下如何判断满二叉树(在该树是完全二叉树的情况下)。如有错误之处,欢迎大家评论留言指出,谢谢大家。