我有一个简单的解决方案来计算完整二进制树中的节点数量:
public int countNodes(TreeNode root) {
if (root == null) { return 0; }
return 1 + countNodes(root.left) + countNodes(root.right);
}
我理解这一点。但是,我知道它必须访问每个节点是低效的。我在网上找到了另一个解决方案:
public int countNodes(TreeNode root) {
if(root==null)
return 0;
int left = getLeftHeight(root)+1;
int right = getRightHeight(root)+1;
if(left==right){
return (2<<(left-1))-1; //having a hard time here
}else{
return countNodes(root.left)+countNodes(root.right)+1;
}
}
public int getLeftHeight(TreeNode n){
if(n==null) return 0;
int height=0;
while(n.left!=null){
height++;
n = n.left;
}
return height;
}
public int getRightHeight(TreeNode n){
if(n==null) return 0;
int height=0;
while(n.right!=null){
height++;
n = n.right;
}
return height;
}
我理解这一点,但我不完全确定我理解条件if(leftHeight == rightHeight)。这是如何运作的?另外,有人可以解释按位操作以及为什么这样做的原因?我不熟悉按位运算符。也许,如果有人可以用非按位代码替换那个条件,并翻译那些将会是完美的!
答案 0 :(得分:4)
我们知道的树的子树中的条件(leftHight == rightHight)
是完整的树意味着当前子树是perfect(完整)二叉树。在完美的二叉树中,除了没有子节点的叶节点之外,每个节点都有两个子节点。
按位语句(2<<(left-1))-1
与Math.pow(2, left) - 1
相同。
一般来说,2的幂可以如下计算:
2<<0 //equals 2 to the power of 1. 2 is shifted zero bits to the left
2<<1 //equals 2 to the power of 2, 2 is shifted 1 bit to the left
2<<2 // equals 2 to the power of 3, 2 is shifted 2 bits to the left
2<<k // equals 2 to the power of k+1, 2 is shifted k bits to the left
现在,如果您查看上面的链接,您将看到高度为h的完美二叉树中的节点数为(2**(k+1))-1
。这是(k + 1)-1的幂。
在上面的代码left
height+1
中注意代码中的加号。因此,(2<<(left-1))-1
实际上正在计算该完美二叉树中的节点数。