递归套路--判断是否是完全二叉树,队列和递归套路,互为对数器

本章有两种实现思路:队列和递归套路,互为对数器

定义:

   一棵树的叶子结点必须先有左节点再有右节点,如果有节点没有左节点,确有右节点,则不是完全二叉树。

思路

  1. 如果左节点为空,右节点不为空,false
  2. 如果之前碰到过不满的节点,再次碰到的左右节点存在的节点,false
static class Node{
        int val;
        Node left;
        Node right;

        public Node(int val) {
            this.val = val;
        }
    }
    public static boolean complateTree(Node head){
        if(head==null)return true;
        //是否碰到过不满的节点
        boolean leaf = false;
        Node l=null;
        Node r=null;
        LinkedList<Node> queue = new LinkedList<>();
        queue.add(head);
        while (!queue.isEmpty()){
            Node cur = queue.poll();
            l=cur.left;
            r=cur.right;
            if((l==null && r!=null) 
            	//leaf为true证明碰到过不满的节点
            	//再次碰到左右子节点存在的节点,就不是完全二叉树
               || (leaf && (l!=null || r!=null))
               ){
                return false;
            }
            if(l!=null){
                queue.add(l);
            }
            if(r!=null){
                queue.add(r);
            }
            if(l==null || r==null){
                leaf=true;
            }
        }
        return true;
    }

递归套路

看下图,以头结点为中线,二叉树是慢慢从左往右依次变满的,根据这个思路,可以总结出几个重点:

  1. 左树完全,右树满,左树高度=右树高度+1
  2. 左树满,右树满,左树高度=右树高度+1
  3. 左树满,右树完全,左树高度=右树高度
  4. 左树满,右树满,左树高度=右树高度
  • 从上面的思路提取公共条件:
    •  1.是否满,
      
    •  2.是否完全,
      
    •  3.树高
      

在这里插入图片描述


    /**
     * 递归套路判断是否是完全二叉树
     * 思路:以头结点为中线,看树是否从左到右依次变满
     *      1.左树完全,右树满,左树高度=右树高度+1
     *      2.左树满,右树满,左树高度=右树高度+1
     *      3.左树满,右树完全,左树高度=右树高度
     *      4.左树满,右树满,左树高度=右树高度
     * 从上面的思路提取公共条件:
     *      1.是否满,
     *      2.是否完全,
     *      3.树高
     */
    static class Info{

        boolean isFull;//是否完全

        boolean isCBT;//是否满

        int height;//树高

        public Info(boolean isFull, boolean isCBT, int height) {
            this.isFull = isFull;
            this.isCBT = isCBT;
            this.height = height;
        }
    }

    public static boolean complateTree2(Node head){
        return process(head).isCBT;
    }
    public static Info process(Node head){
        if(head==null){
            return new Info(true,true,0);
        }
        Info leftInfo = process(head.left);
        Info rightInfo = process(head.right);
        //收集左右子树信息,拼装返回信息
        int height= Math.max(leftInfo.height, rightInfo.height)+1;
        boolean isFull= leftInfo.isFull && rightInfo.isFull && leftInfo.height== rightInfo.height;
        boolean isCBT = false;
        if(leftInfo.isCBT && rightInfo.isFull && leftInfo.height==rightInfo.height+1){
            isCBT=true;
        }
        if(leftInfo.isFull && rightInfo.isFull && leftInfo.height==rightInfo.height+1){
            isCBT=true;
        }
        if(leftInfo.isFull && rightInfo.isCBT && leftInfo.height==rightInfo.height){
            isCBT=true;
        }
        if(leftInfo.isFull && rightInfo.isFull && leftInfo.height==rightInfo.height){
            isCBT=true;
        }
        return new Info(isFull,isCBT,height);

    }
    

生成测试二叉树


    public static Node generateRandomNode(int maxLevel,int maxValue){
        return generate(1,maxLevel,maxValue);
    }

    private  static Node generate(int level,int maxLevel,int maxValue){
        if(level>maxLevel || Math.random()<0.5){
            return null;
        }
        Node head = new Node((int)(Math.random()*maxValue));
        head.left=generate(level+1,maxLevel,maxValue);
        head.right=generate(level+1,maxLevel,maxValue);
        return head;
    }

测试


    public static void main(String[] args) {
          Node head = new   Node(1);
        head.left = new   Node(2);
        head.right = new   Node(3);
        head.left.left = new   Node(4);
        head.left.right = new   Node(5);
        head.right.left = new   Node(6);
        head.right.right = new   Node(7);

        System.out.println(complateTree(head));
        System.out.println(complateTree2(head));

        int maxLevel=5;
        int maxValue=5000;
        int testTimes=10000000;
        for (int i = 0; i < testTimes; i++) {
            Node node = generateRandomNode(maxLevel, maxValue);
            if(complateTree(node)!=complateTree2(node)){
                System.out.println("Oops");
            }
        }
        System.out.println("finished");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值