二叉树

几种比较容易混淆的二叉树

  • 满二叉树:高度为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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值