几种比较容易混淆的二叉树
- 满二叉树:高度为h,并且由2^h-1个结点组成的二叉树,叶子节点都在最后一层,除了最后一层,其他层的节点个数都要达到最大
判断满二叉树
public class Solution {
boolean isFullTree(TreeNode root){
if(root==null)
return false;
if(root.left==null && root.right==null)
return true;
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
if(leftDepth!=rightDepth)
return false;
if(isFullTree(root.left)&&isFullTree(root.right))
return true;
else
return false;
}
public int maxDepth (TreeNode root) {
if(root==null)
return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
}
- 完全二叉树:叶子节点都在最后两层,最后一层的叶子节点都靠左排列,除了最后一层,其他层的节点个数都要达到最大
public class Solution {
public boolean isCBT(TreeNode root){
if(root == null)
return true;
Queue<TreeNode>queue = new LinkedList<>();
boolean leaf = false; //如果碰到了 某个结点孩子不全就开始 判断是不是叶子这个过程
queue.add(root);
TreeNode top = null,L = null,R = null;
while(!queue.isEmpty()){
top = queue.poll();
L = top.left; R = top.right;
//第一种情况
if((R != null && L == null))
return false;
//第二种情况 开启了判断叶子的过程 而且又不是叶子 就返回false
if(leaf && (L != null || R != null)) //以后的结点必须是 左右孩子都是null
return false;
if(L != null)
queue.add(L);
//准确的说是 只要孩子不全就开启leaf,
//但是前面已经否定了有右无左的情况,这里只要判断一下右孩子是不是为空就可以了(如果为空就开启leaf)
if(R != null)
queue.add(R);
else
leaf = true;
}
return true;
}
}
- 二叉搜索树:又叫二叉查找树,二叉排序树。任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。中序遍历即为升序
public class Solution {
public boolean isBST(TreeNode root) {
if(root == null)
return true;
Stack<TreeNode>stack = new Stack<>();
TreeNode cur = root;
TreeNode pre = null;
while(!stack.isEmpty() || cur != null){
if(cur != null){
stack.push(cur);
cur = cur.left;
}else {
cur = stack.pop();
if(pre != null && cur.val <= pre.val)
return false;
pre = cur;
cur = cur.right;
}
}
return true;
}
}
- 二叉平衡树:又叫AVL树。它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。其高度一般都良好地维持在O(log(n)),大大降低了操作的时间复杂度。
是否二叉平衡树
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root==null)
return true;
Stack<TreeNode> stack=new Stack<TreeNode>();
stack.push(root);
TreeNode node;
while(stack.size()!=0){
node=stack.pop();
if(Math.abs(maxDepth(node.left)-maxDepth(node.right))>1)
return false;
if(node.left!=null)
stack.push(node.left);
if(node.right!=null)
stack.push(node.right);
}
return true;
}
public int maxDepth (TreeNode root) {
if(root==null)
return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
}
但是上面这种做法并不好,因为一个节点遍历不止一次,深度越大的节点遍历次数越多,所以我们希望数从下自上遍历,一旦碰到非二叉平衡树即停止遍历return false
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
return isBalance(root,new int[1]);
}
public boolean isBalance(TreeNode root,int[] depth){
if(root==null){
depth[0]=0;
return true;
}
boolean left=isBalance(root.left,depth);
int leftDepth=depth[0];
boolean right=isBalance(root.right,depth);
int rightDepth=depth[0];
if(left && right){
depth[0]=Math.max(leftDepth,rightDepth)+1;
if(Math.abs(leftDepth-rightDepth)<=1){
return true;
}
}
return false;
}
}
参考资料
https://www.cnblogs.com/jkzr/p/10701386.html