二叉树的判断

二叉树的判断

二叉树判断

中序遍历如果总是升序,那他肯定是二叉树,如果出现某个降序,他肯定不是二叉树

/**
     * 递归判断是否为二叉树
     * @param head
     * @return
     */
    public static boolean checkBST(Node head) {
        int preValue = Integer.MIN_VALUE;
        if (head == null) {
            return true;
        }
        boolean isLeftBst = checkBST(head.left);
        if (!isLeftBst) {
            return false;
        }
        if (head.value <= preValue) {
            return false;
        } else {
            preValue = head.value;
        }
        return checkBST(head.right);

    }

    /**
     * 非递归方式判断是否为二叉树
     * 非递归方式实现的中序遍历,在出栈的之后不是打印而是看结点值是否小于设置的最小值。
     * 小于的话就不是二叉树
     * 不小于的话就继续判断下面结点,让这个结点的值作为最小值去跟其他结点值比较
     * @param head
     * @return
     */
    public static boolean checkBST3(Node head) {
        if (head != null) {
            int preValue = Integer.MIN_VALUE;
            Stack<Node> stack = new Stack<Node>();
            while (!stack.isEmpty() || head != null) {
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                } else {
                    head = stack.pop();
                    if (head.value <= preValue) {
                        return false;
                    } else {
                        preValue = head.value;
                    }
                    head = head.right;
                }
            }
        }
        return true;
    }

满二叉树判断

就是对于一棵二叉树,可以通过从左孩子树和右孩子树拿消息然后解出答案就可以使用树型DP套路来处理,比如如果找出左孩子树需要什么,右孩子树需要什么,然后看整棵树需要什么,取出全集。

概念:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这课二叉树为满二叉树;

判断:这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个结点的二叉树。

/**
     * 判断是否为满二叉树
     * @param head
     * @return
     */
    public static boolean isF(Node head) {
        if (head == null) {
            return true;
        }
        Info data = f(head);
        return data.nodes == (1 << data.height - 1);

    }

    /**
     * 存储高度和结点
     */
    public static class Info{
        public int height;
        public int nodes;

        public Info(int h, int n) {
            height = h;
            nodes = n;
        }
    }

    /**
     * 计算高度和结点
     * @param x
     * @return
     */
    public static Info f(Node x) {
        if (x == null) {
            return new Info(0, 0);
        }
        Info leftData = f(x.left);
        Info rightData = f(x.right);
        int height = Math.max(leftData.height, rightData.height) + 1;
        int nodes = leftData.nodes + rightData.nodes + 1;
        return new Info(height, nodes);
    }

完全二叉树判断

概念:完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^h -1个节点。

判断:按照深度遍历,第一个条件是在任意一个结点,如果有右孩子没有左孩子,就返回false;第二个条件,在不违反第一个条件下,如果遇到了第一个左右孩子不全的,那么下面的结点都是叶子结点。

/**
     * 判断是否为完全二叉树
     * 第一个条件是有右孩子没有左孩子就返回false
     * 第二个条件是在第一个条件下,遇到的第一个左右孩子不全的结点,那么后面的结点都是叶子结点,不能返回false
     * @param head
     * @return
     */
    public static boolean isCBT(Node head) {
        if (head == null) {
            return true;
        }
        LinkedList<Node> queue = new LinkedList<>();
//        是否遇到过左右两个孩子不双全的结点
        boolean leaf = false;
        Node l = null;
        Node r = null;
        queue.add(head);
        while (!queue.isEmpty()) {
             head = queue.poll();
            l = head.left;
            r = head.right;
//            (l == null && r != null):表示第一个条件有右孩子,没有左孩子,返回false
//            (leaf && (l != null || r != null)):表示第二个条件,虽然遇到了左右孩子不双全的结点,但是不满足第一条件,所以返回false
            if (
                    (leaf && (l != null || r != null))
                            ||
                            (l == null && r != null)
            ) {
                return false;
            }
//            如果左孩子不为空,加入队列
            if (l != null) {
                queue.add(l);
            }
//            如果右孩子不为空,加入队列
            if (r != null) {
                queue.add(r);
            }
//            如果左孩子为空或者右孩子为空,就是遇到了左右孩子不双全的情况,那么leaf就是true
            if (l == null || r == null) {
                leaf = true;
            }
            
        }
        return true;
    }

搜索二叉树判断

概念:前面介绍的树,都没有数值的,而二叉搜索树是有数值的了,二叉搜索树是一个有序树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

判断:要满足左孩子是搜索二叉树,右孩子也是搜索二叉树,还要知道左孩子的最大值是否大于x,右孩子的最小值是否小于x,因为使用递归法,左孩子和右孩子的处理不一样就不能用递归,所以,可以取左孩子和右孩子的并集,也就是要知道整棵树是否为二叉树,然后左孩子的最大值和右孩子的最小值。

/**
     * 判断是否为搜索二叉树
     * 左孩子的最大值如果大于根结点,返回false,否则是搜索二叉树
     * 右孩子的最小值如果小于根结点,返回false,否则是搜索二叉树
     * @param x
     * @return
     */
    public static ReturnData process(Node x) {
        if (x == null) {
            return null;
        }
        ReturnData leftData = process(x.left);
        ReturnData rightData = process(x.right);
        int min = x.value;
        int max = x.value;
        if (leftData != null) {
            min = Math.min(min, leftData.min);
            max = Math.max(max, rightData.max);
        }
        boolean isBST = true;
        if (leftData != null && (!leftData.isBST || leftData.max >= x.value)) {
            isBST = false;
        }
        if (rightData != null && (!rightData.isBST || x.value >= rightData.min)) {
            isBST = false;
        }
        return new ReturnData(isBST, min, max);
    }

    /**
     * 存
     * 是否为搜索二叉树字段
     * 左孩子最大值字段
     * 右孩子最小值字段
     */
    public static class ReturnData{
        public boolean isBST;
        public int min;
        public int max;

        public ReturnData(boolean is, int mi, int max) {
            isBST = is;
            min = mi;
            max = max;
        }

    }

平衡二叉树/平衡搜索二叉树判断

整棵树的左孩子树要是平衡二叉树,右孩子树也要是平衡二叉树;并且他们的差值不能大于1;所以在实现的过程中要知道左孩子是否为二叉树和左孩子的高度,右孩子也是一样。

 /**
     * 调用判断平衡二叉树函数返回
     * @param head
     * @return
     */
    public static boolean isBalanced(Node head) {
        return process2(head).isBalanced;
    }

    /**
     * 存
     * 是否为平衡二叉树字段
     * 高度
     */
    public static class ReturnType{
        public boolean isBalanced;
        public int height;

        public ReturnType(boolean isB, int hei) {
            isBalanced = isB;
            height = hei;
        }
    }

    /**
     * 判断是否为平衡二叉树
     * 第一个条件是左孩子为平衡二叉树
     * 第二个条件是右孩子为平衡二叉树
     * 第三个条件是左孩子和右孩子高度差不能小于1;
     * 三个条件缺一不可
     * @param x
     * @return
     */
    public static ReturnType process2(Node x) {
        if (x == null) {
            return new ReturnType(true, 0);
        }
        ReturnType leftType = process2(x.left);
        ReturnType rightType = process2(x.right);
        int height = Math.max(leftType.height, rightType.height) + 1;
        boolean isBalanced = leftType.isBalanced && rightType.isBalanced
                && Math.abs(leftType.height - rightType.height) < 2;
        return new ReturnType(isBalanced, height);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值