题目
求完全二叉树的节点个数
- 传统的递归遍历能求,下面通过完全二叉树的性质来进行优化
- 完全二叉树:节点从上到下,从左到右依次排列;满二叉树:除了叶子节点,任意节点的子节点都是满的
- 如果完全二叉树的右子树的高度+1和整棵树的高度一致,那么左子树一定是满二叉树,可以直接求得答案
- 如果完全二叉树的右子树高度+1和左子树不一致,那么因为完全二叉树的排列性质,右子树一定是满二叉树,右子树可以求得答案
- 对于没有直接求得答案的子树,递归需要求解的子树部分(子树也是完全二叉树),根据上面的规律求解
// level:当前节点的深度,height:以当前节点为顶点的完全二叉树的深度
function process(ndoe, level, height) {
// 只剩一个节点了
if (level === height) {
return 1;
}
// 如果右树高度和完全二叉树高度一致,左树是个满二叉树,需要求右树完全二叉树高度
if (getLevel(node.right, level + 1) === height) {
// 2^(h-level)-1+1
return (1 << (height - level)) + process(node.right, level + 1, height);
} else {
// 如果右树高度不一致,右树是个满二叉树,求左树完全二叉树高度
return (1 << (height - level - 1)) + process(node.left, level + 1, height);
}
}
process(node, 1, getLevel(node, 1));
function getLevel(node, level) {
while (node !== null) {
level++;
node = node.left;
}
return level - 1;
}