已知一棵完全二叉树, 求其节点的个数
要求: 时间复杂度低于O(N), N为这棵树的节点个数
结论:满二叉树:高度为L,结点个数 2^L - 1个
先遍历左边界,求出完全二叉树的高度h
然后遍历树的右子树的左边界,看它到没到最后一层,
如果到了最后一层,那么证明它的左子树是满的,高度是h-1 左子树的结点数2^(h-1) - 1 + 当前节点 + 递归求解 右子树的结点的个数
如果没到最后一层,那么证明它的右子树是满的,高度是h-2 右子树的结点数2^(h-2) - 1 + 当前节点 + 递归求解 左子树的结点的个数
public class CompleteTreeNodeNumber {
public static int completeTreeNodeNumber(Tree tree){
if(tree == null) return 0;
return comNum(tree, 1, treeHigh(tree));
}
public static int comNum(Tree tree, int level, int high){
if(level == high) return 0;
int l = treeHigh(tree.right);
//当前结点的右孩子的最左结点到达树的最下面,则左孩子是满二叉树,高度是high-level
if(l == high - level){
return comNum(tree.right, level + 1, high) + (1 << (high - level));
} else{
//当前结点的右孩子的最左结点没有到达树的最下面,则右孩子是满二叉树,高度是high-level-1
return comNum(tree.left, level + 1, high) + (1 << (high - level - 1));
}
}
public static int treeHigh(Tree tree){
if(tree == null) return 0;
int high = 1;
while(tree.left != null){
high++;
tree = tree.left;
}
return high;
}
}