题目:

1
2
3
4
给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例:

1
2
3
4
5
6
7
8
9
输入: 
1
/ \
2 3
/ \ /
4 5 6

输出: 6

分析:

1
可以使用深度优先遍历所有节点。

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 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;
}
};

利用完全二叉树性质,作者zuo-10

链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/solution/c-san-chong-fang-fa-jie-jue-wan-quan-er-cha-shu-de/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
// 统计树的深度
int countLevels(TreeNode* root) {
int levels = 0;
while (root) {
root = root->left; levels += 1;
}
return levels;
}
int countNodes(TreeNode* root){
// 2. 利用完全二叉树性质简化遍历次数
if(root == nullptr) return 0;
int left_levels = countLevels(root->left);
int right_levels = countLevels(root->right);
// 左子树深度等于右子树深度, 则左子树是满二叉树
if(left_levels == right_levels){
return countNodes(root->right) + (1<<left_levels);//2的树深度次方
}else{
return countNodes(root->left) + (1<<right_levels);
}
}
};
/*
如果知道子树是满二叉树,那么就可以轻松得到该子树的节点数目:(1<<depth) - 1; // depth为子树的深度;为了加快幂的运算速度,可以使用移位操作符
接着我们只需要接着对另一子树递归即可
时间复杂度为O(logn * logn),空间复杂度为O(1)【不考虑递归调用栈】
*/

官方方法:二分查找+位运算(需仔细学习)

完全二叉树的节点个数 - 完全二叉树的节点个数 - 力扣(LeetCode) (leetcode-cn.com)