题目描述
给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1 ~ 2^h 个节点。
示例:
输入:
1
/
2 3
/ /
4 5 6
输出: 6
题目链接: https://leetcode-cn.com/problems/count-complete-tree-nodes/
思路1
使用 dfs。代码如下:
/**
* 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==nullptr) return 0;
return countNodes(root->left)+countNodes(root->right)+1;
}
};
思路2
使用bfs。代码如下:
/**
* 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==nullptr) return 0;
queue<TreeNode*> q;
q.push(root);
int cnt = 0;
while(!q.empty()){
TreeNode* node = q.front(); q.pop();
cnt++;
if(node->left!=nullptr) q.push(node->left);
if(node->right!=nullptr) q.push(node->right);
}
return cnt;
}
};
思路3
上面的两种方法都是使用遍历来做,没有使用到完全二叉树的性质。
完全二叉树是一棵空树或者它的叶子节点只出在最后两层,若最后一层不满则叶子节点只在最左侧。如果每一层的节点都是满的,则称为满二叉树。对于一个高度为 d 的满二叉树来讲,树中节点的个数为 (2^d-1)。
对于完全二叉树中的一个节点:
- 如果该节点左子树的高度等于该节点右子树的高度,都是 h,则说明该节点的左子树是满的,通过公式 (2^h-1) 计算左子树的节点个数,再加上根节点共 (2^h) 个节点,然后递归计算右子树的节点个数;
- 如果左子树的高度不等于右子树的高度,则说明最后一层不满,但倒数第 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 countNodes(TreeNode* root) {
if(root==nullptr) return 0;
int left = getHeight(root->left);
int right = getHeight(root->right);
if(left==right){
return pow(2, left) + countNodes(root->right);
}else{
return pow(2, right) + countNodes(root->left);
}
}
int getHeight(TreeNode* root){
if(root==nullptr) return 0;
return max(getHeight(root->left)+1, getHeight(root->right)+1);
}
};