二分搜索—— 完全二叉树统计节点个数
2017-06-30 19:55
232 查看
注意:做2的幂时不要用Math.pow,这样会超时。用1<< a 这个方法来得到2的a次幂!!!
参考:
http://blog.csdn.net/freeelinux/article/details/53679708(二分法,C++) http://www.cnblogs.com/grandyang/p/4567827.html (递归)
【题目】
题目链接:https://leetcode.com/problems/count-complete-tree-nodes/#/description
给定一棵完全二叉树的根节点root,返回这棵树的节点个数。如果完全二叉树的节点数为N,请实现时间复杂度低于O(N)的解法。
给定树的根结点root,请返回树的大小。
思路:
计算完全二叉树最左节点的位置,目的是计算出二叉树的高度,然后再找到右子树的最左节点的位置与之做比较,则有以下两种情况:
1) 如果右子树的最左节点刚好到达最下面的一层的话(如下图),那么说明该树的左子树是一颗满二叉树,那么可以根据二叉树的性质计算出左子树的节点个数,再加上根节点,剩下需要计算的就是右子树的个数了,采用递归的方式。
2) 如果右子树的最左节点不能到达最下面的一层的话(如下图),说明右子树也是一颗满二叉树,只是层数少了,同理,根据二叉树的性质计算出右子树的节点个数,再加上根节点的,剩下的只需计算左子树节点个数,同样采用递归方式。
这种方式的复杂度肯定比遍历的复杂度低。
遍历的方式,时间复杂度是O(N)
采用这种方式,时间复杂度为O((logN)^2),即二叉树高度的平方。
其实这种方法的思想是二分思想,其实就是在看完全二叉树最后一层的最右节点到底处在什么样的位置上。
参考:
http://blog.csdn.net/freeelinux/article/details/53679708(二分法,C++) http://www.cnblogs.com/grandyang/p/4567827.html (递归)
【题目】
题目链接:https://leetcode.com/problems/count-complete-tree-nodes/#/description
给定一棵完全二叉树的根节点root,返回这棵树的节点个数。如果完全二叉树的节点数为N,请实现时间复杂度低于O(N)的解法。
给定树的根结点root,请返回树的大小。
思路:
计算完全二叉树最左节点的位置,目的是计算出二叉树的高度,然后再找到右子树的最左节点的位置与之做比较,则有以下两种情况:
1) 如果右子树的最左节点刚好到达最下面的一层的话(如下图),那么说明该树的左子树是一颗满二叉树,那么可以根据二叉树的性质计算出左子树的节点个数,再加上根节点,剩下需要计算的就是右子树的个数了,采用递归的方式。
2) 如果右子树的最左节点不能到达最下面的一层的话(如下图),说明右子树也是一颗满二叉树,只是层数少了,同理,根据二叉树的性质计算出右子树的节点个数,再加上根节点的,剩下的只需计算左子树节点个数,同样采用递归方式。
这种方式的复杂度肯定比遍历的复杂度低。
遍历的方式,时间复杂度是O(N)
采用这种方式,时间复杂度为O((logN)^2),即二叉树高度的平方。
其实这种方法的思想是二分思想,其实就是在看完全二叉树最后一层的最右节点到底处在什么样的位置上。
public class CountCompleteBinaryTreeNodes { class TreeNode{ int val; TreeNode left=null; TreeNode right=null; public void Node(int val){ this.val=val; } } //计算完全二叉树的层数 public int getDepth(TreeNode root){ if(root==null) return 0; int dep=1; while(root.left!=null){ root=root.left; dep++; } return dep; } //统计完全二叉树的节点个数 public int countNodes(TreeNode root){ if(root==null) return 0; else if(root.left==null&&root.right==null) return 1; int left_left_level=getDepth(root); //根节点左子树最左节点的层数 int right_left_level=0; //根节点右子树最左节点的层数 if(root.right!=null){ right_left_level=getDepth(root.right); } right_left_level++; //加上根节点原本的一层 if(left_left_level==right_left_level){ return (1<<(right_left_level-1))+countNodes(root.right); } else{ //left_left_level > right_left_level return (1<<(right_left_level-1))+countNodes(root.left); } } }
相关文章推荐
- 完全二叉树统计节点个数【使用二分搜索】
- 二叉树问题---统计完全二叉树的节点个数
- 二分搜索树非递归节点计数删除
- LeetCode 222. Count Complete Tree Nodes(完全二叉树节点数统计)
- 二分搜索树的实现以及各种操作(支持重复节点)
- 【二叉树】二分查找树,中序遍历,统计出现次数最多的节点【Add to List 501. Find Mode in Binary Search Tree】
- 二分搜索树的删除节点操作
- [itint5]完全二叉树节点个数的统计
- 5-3 二分搜索树的节点插入(插入新的节点)
- Count Complete Tree Nodes 统计完全二叉树的节点数
- 树——统计完全二叉树的节点数目
- 5-8 二分搜索树的删除,删除一个节点的步骤2
- [各种面试题] 完全二叉树节点个数的统计
- nyoj914(二分搜索+贪心)
- 二叉树问题---寻找搜索二叉树中两个错误的节点
- Hack in Lucene.Net之为什么无法在搜索时统计分类下相关结果数或者实现Group By效果
- Ackerman函数的递归、全排列的递归实现、整数划分的递归、二分搜索的递归、合并排序的递归、.快速排序
- 二叉树 遍历|统计叶子节点|求深度|交换左右子树|查找是否存在某个特定叶子节点练习题
- 博客学习十——二分搜索、扫描算法、C难点
- 标题:五星填数 如【图1.png】的五星图案节点填上数字:1~12,除去7和11。 要求每条直线上数字和相等。 如图就是恰当的填法。 请你利用计算机搜索所有可能的填法有多少种。 注意:旋转或镜