题目: 给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例:
方法一:迭代深度优先搜索
/*
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
int count=1;
Stack<TreeNode> stack=new Stack<>();
if(root==null)return 0;
TreeNode root1=root;
stack.add(root1);
TreeNode tmp=root1;
while(!stack.isEmpty()||tmp.left!=null||tmp.right!=null) {
if(tmp.left!=null) {//左子树不为空
count++;
stack.add(tmp.left);
tmp=tmp.left;
}else {//左子树为空,查看右子树
//tmp=tmp.right;
if(tmp.right!=null) {
count++;
stack.add(tmp.right);
tmp=tmp.right;
}else {//右子树也为空
TreeNode t=stack.pop();
if(!stack.isEmpty()){
tmp=stack.peek();
if(tmp.left==t){
tmp.left=null;
}
if(tmp.right==t){
tmp.right=null;
}
}
}
}
}
return count;
}
}
方法二:递归深度优先搜索
class Solution {
public int countNodes(TreeNode root) {
if(root == null) {
return 0;
}
int left = countNodes(root.left);
int right = countNodes(root.right);
return left+right+1;
}
}
public int countNodes(TreeNode root) {
if (root == null){
return 0;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
方法三:二分查找+位运算
class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
int level = 0;
TreeNode node = root;
while (node.left != null) {
level++;
node = node.left;
}
int low = 1 << level, high = (1 << (level + 1)) - 1;
while (low < high) {
int mid = (high - low + 1) / 2 + low;
if (exists(root, level, mid)) {
low = mid;
} else {
high = mid - 1;
}
}
return low;
}
public boolean exists(TreeNode root, int level, int k) {
int bits = 1 << (level - 1);
TreeNode node = root;
while (node != null && bits > 0) {
if ((bits & k) == 0) {
node = node.left;
} else {
node = node.right;
}
bits >>= 1;
}
return node != null;
}
}
方法四:位移运算
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
int left = countLevel(root.left);
int right = countLevel(root.right);
if(left == right){
return countNodes(root.right) + (1<<left);
}else{
return countNodes(root.left) + (1<<right);
}
}
private int countLevel(TreeNode root){
int level = 0;
while(root != null){
level++;
root = root.left;
}
return level;
}
}
方法五:位运算非递归
class Solution {
public int countNodes(TreeNode root) {
if(root == null) return 0;
int left = countLevel(root.left);
int count = 0;
while(root != null){
int right = countLevel(root.right);
if(right == left){
count+=(1<<left);
root = root.right;
}else{
count+=(1<<right);
root = root.left;
}
left--;
}
return count;
}
public int countLevel(TreeNode root){
if(root == null) return 0;
int h = 0;
while(root != null){
root = root.left;
h++;
}
return h;
}
}