/**
* 二叉树节点的定义。
* public class TreeNode {
* int val; // 节点的值
* TreeNode left; // 左子节点
* TreeNode right; // 右子节点
* TreeNode(int x) { val = x; } // 构造函数初始化节点值
* }
*/
class Solution {
// 计算完全二叉树的节点总数
public int countNodes(TreeNode root) {
// 如果根节点为null,说明这棵树是空树,节点数为0
if (root == null) {
return 0;
}
// 计算左子树的高度
int left = countLevel(root.left);
// 计算右子树的高度
int right = countLevel(root.right);
// 如果左子树和右子树的高度相等,说明左子树是一个满二叉树
if (left == right) {
// 左子树是满二叉树,其节点数为 2^left - 1,加上根节点则为 2^left
// 然后递归计算右子树的节点总数
return countNodes(root.right) + (1 << left); // 1<<left 相当于 2^left
} else {
// 如果左右子树的高度不相等,说明右子树是一个满二叉树
// 右子树的节点数为 2^right - 1,加上根节点为 2^right
// 然后递归计算左子树的节点总数
return countNodes(root.left) + (1 << right); // 1<<right 相当于 2^right
}
}
// 计算树的高度,只需沿着左子树一直向下遍历
private int countLevel(TreeNode root) {
int level = 0;
// 不断遍历左子树,直到遍历到null为止,记录遍历的层数
while (root != null) {
level++; // 每向下遍历一层,层数加1
root = root.left; // 沿着左子树继续向下遍历
}
// 返回树的高度
return level;
}
}