递归套路-是否是满二叉树

package cn.bugstack.session;

/**
 * @Description 满二叉树:树上节点数是层数h的关系  2^h-1
 * @ClassName Code10_FullTree
 * @Author bzh
 * @Version 1.0.0
 * @CreateTime 2023-08-25 15:59 - 星期五
 */
public class Code10_FullTree {
    static class Node{
        int val;
        Node left;
        Node right;

        public Node(int val) {
            this.val = val;
        }
    }
    static class Info{
        int size;
        int hight;

        public Info(int size, int hight) {
            this.size = size;
            this.hight = hight;
        }
    }

    /**
     * 论证公示:总结点数(size),层高(h);size=2^h-1
     * process()方法:
     *      1.收集左右树各自的节点数
     *      2.收集左右树的层高
     *  isFull()方法:
     *      收集process()方法的结果,进行公式判断
     *  注意:头结点为空的也算满二叉树
     *  
     *  归纳信息:
     *      左右子树节点数:size
     *      左右子树层高:height
     *  
     *  
     */
    public static boolean isFull(Node head){
        if(head==null)return true;
        Info info = process(head);
        return info.size==(1<< info.hight)-1;
    }

    public static Info process(Node head){
        if(head==null){
            return new Info(0,0);
        }

        Info leftInfo = process(head.left);
        Info rightInfo = process(head.right);
        int size = leftInfo.size+ rightInfo.size+1;
        int hight = Math.max(leftInfo.hight, rightInfo.hight)+1;
        return new Info(size,hight);
    }



    static class Info2{
        boolean isFull;
        int height;

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

    /**
     *  暴力方法:
     *      1.收集左右子树是不是满二叉树
     *      2.收集左右子树的层高
     *  
     *  论证方法:
     *      1.左右子树是满二叉树
     *      2.左右子树层高相等
     *  
     *  归纳收集信息:
     *      层高;height
     *      是否是满二叉树;ifFull
     */
    public static boolean isFull2(Node head){
        if(head==null)return true;
        Info2 info2 = process2(head);
        return info2.isFull;

    }

    public static Info2 process2(Node head){
        if(head==null){
            return new Info2(true,0);
        }
        Info2 leftInfo = process2(head.left);
        Info2 rightInfo = process2(head.right);
        boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height== rightInfo.height;
        int height = Math.max(leftInfo.height, rightInfo.height)+1;
        return new Info2(isFull,height);
    }


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

    public 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) {
        int maxLevel=5;
        int maxValue=100;
        int testTimes=1000000;
        for (int i = 0; i < testTimes; i++) {
            Node node = generateRandom(maxLevel, maxValue);
            boolean full = isFull(node);
            boolean full2 = isFull2(node);
            if(full != full2){
                System.out.println("Oop");
                isFull(node);
            }
        }
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值