题目描述
给你一棵 完全二叉树 的根节点 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;
}
利用满二叉树的特点求节点个数*(递归)
- 传入的参数:node (当前节点)
- 终止条件:
- 当前节点为null
- 当前子树为满二叉树,返回当前子树的节点数
难点:如何判断当前子树为满二叉树呢?
答案是:左子树左侧高度==右子树右侧高度
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;
};
总结
本题直接使用后序遍历会很简单,但我还是想学习下如何判断满二叉树(在该树是完全二叉树的情况下)。如有错误之处,欢迎大家评论留言指出,谢谢大家。