给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-complete-tree-nodes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
首先就普通二叉树的方法:递归法、迭代法
递归法:
```cpp
```cpp
```cpp
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
return nodenum(root);
}
private:
int nodenum(TreeNode* node)
{
if(node == NULL) return 0;
int leftnum = nodenum(node->left);//左
int rightnum = nodenum(node->right);//右
int treenode = 1+leftnum + rightnum;//中
return treenode;
}
};
迭代法:借助队列,类似于层序遍历。
首先定义一个队列:queue<TreeNode*> qu 用来保存每一层的二叉树节点,借助队列先进先出的特点。
```cpp
class Solution { public:
int countNodes(TreeNode* root) {
queue<TreeNode *> qu;
if(root == NULL) return 0;
int result=0;
qu.push(root);
while(!qu.empty())
{
int size = qu.size();
for(int i=0;i<size;i++)
{
TreeNode* node= qu.front();
qu.pop();
result++;
if(node->left) qu.push(node->left);
if(node->right) qu.push(node->right);
}
}
return result;
} }; ```
以上两种方法都是针对普通的二叉树的,但是当对象是完全二叉树,我们可以进一步优化算法。
对于完全二叉树有两种情况
1、为满二叉树,则他的节点是可以通过公式算出来的:(2的深度次方)-1。此时根节点的深度为1。
2、最后一层节点没有满,最后一层节点的个数在1到2的深度-1次方。
我们可以判断是否是满二叉树,向左向右计算深度,如果左右深度相同则是满二叉树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
if(root==NULL) return 0;
TreeNode * left = root->left;
TreeNode * right = root->right;
int leftdepth = 0;
int rightdepth =0;
while(left)
{
left=left->left;
leftdepth++;
}
while(right)
{
right=right->right;
rightdepth++;
}
if(leftdepth==rightdepth)//判断是否是满二叉树
{
return (2<<leftdepth)-1;
}
return countNodes(root->left)+countNodes(root->right)+1;//!!!!!!!!!!!!!!!!!!
}
};
时间复杂度:O(log n × log n)
空间复杂度:O(log n)