题目:
Given a complete binary tree, count the number of nodes.
Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
思路:
最简单的思路:return 1 + countNodes(root->left) + countNodes(root->right);
可惜超时了。由于是完全二叉树,根结点的左右子树至少有一个是满二叉树,因此可以在递归之前先算出满二叉树的结点数目。
代码1:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode *root)
{
if(root == NULL)
return 0;
int height = 0;
TreeNode *leftNode = root , *rightNode = root;
while(leftNode && rightNode)
{
leftNode = leftNode->left;
rightNode = rightNode->right;
height++;
}
//如果leftNode为空,说明是满二叉树,返回2^h-1
if(leftNode == NULL)
return (1 << height) - 1;//这里一定要加(),因为-的优先级高于移位
else
return 1 + countNodes(root->left) + countNodes(root->right);
}
};
代码2:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int height(TreeNode *root)
{
if(root == NULL)
return -1; //叶结点的子节点返回-1,这把叶结点那一行抵消掉了,故计算的高度不包括最后一行
else
return 1 + height(root->left);
}
int countNodes(TreeNode *root)
{
int h = height(root);
if(h < 0)
return 0;
if(height(root->right) == h-1)
return (1 << h) + countNodes(root->right);//如果root->right返回h-1,则说明最后一行的最后一个结点位于右子树,即说明左子树是满二叉树,左子树的结点数目即为2^h-1,再加上根结点就是2^h,然后+右子树的结点数
else
return (1 << h-1) + countNodes(root->left);//如果root->right返回的<h-1,则说明最后一行的最后一个结点位于左子树,即说明右子树的满二叉树,右子树的结点数目即为2^(h-1)-1,再加上根结点就是2^(h-1),然后+左子树的结点数
}
};
代码3:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int height(TreeNode *root)
{
if(root == NULL)
return -1; //叶结点的子节点返回-1,这把叶结点那一行抵消掉了,故计算的高度不包括最后一行
else
return 1 + height(root->left);
}
int countNodes(TreeNode *root)
{
int result = 0;
int h = height(root);
if(h < 0)
return 0;
while(root)
{
if(height(root->right) == h-1)
{
result += 1<<h;
root = root->right;
}
else
{
result += 1<<h-1;
root = root->left;
}
h--;
}
return result;
}
};