验证搜索二叉树

package class07;

/**
 * 验证搜索二叉树
 * <p>
 * 另:判断是否是平衡搜索二叉树?
 * 写两个函数,一个是判断是否是平衡二叉树,一个是判断是否是搜索二叉树。
 * 将两个布尔值取与(即&&)的关系,就是最后结果。
 */
public class Code05_IsBinarySearchTree {
    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }

    /**
     * 定义一个Info,包含三个信息:
     * 是否是搜索树,当前树的最大值,当前树的最小值。
     */
    public static class Info {
        boolean isSearch;
        int max;
        int min;

        public Info(boolean is, int ma, int mi) {
            isSearch = is;
            max = ma;
            min = mi;
        }
    }

    /**
     * @param root 根节点
     * @return 是否是搜索树
     */
    public boolean isValidBST(TreeNode root) {
        return process(root).isSearch;
    }

    public static Info process2(TreeNode x) {
        //如果x是null,则返回null。也就是说,下游向上返回的Info,我们需要在上游判断这个Info是否为null。
        if (x == null) {
            return null;
        }
        Info leftInfo = process2(x.left);//x的左节点,递归去。最后返回leftInfo。
        Info rightInfo = process2(x.right);//x的右节点,递归去。最后返回rightInfo。
        int max = x.val;//先将最大值标记为x的值
        int min = x.val;//先将最小值标记为x的值
        if (leftInfo != null) {//如果leftInfo不为空
            max = Math.max(leftInfo.max, max);//拿leftInfo的最大值和max比较,谁大,谁就是新的max。
            min = Math.min(leftInfo.min, min);//拿leftInfo的最小值和min比较,谁小,谁就是新的min。
        }
        if (rightInfo != null) {//如果rightInfo不为空
            max = Math.max(rightInfo.max, max);//拿rightInfo的最大值和max比较,谁大,谁就是新的max。
            min = Math.min(rightInfo.min, min);//拿rightInfo的最小值和min比较,谁小,谁就是新的min。
        }
        //先定义当前树是搜索树。在后边的判断中,只要有一处违反了搜索树的要求,就将isSearch修改为false。
        boolean isSearch = true;
        if (leftInfo != null && !leftInfo.isSearch) {//如果leftInfo不是空,并且leftInfo不是搜索树
            isSearch = false;//那么就将isSearch修改成false。
        }
        if (rightInfo != null && !rightInfo.isSearch) {//如果rightInfo不是空,并且rightInfo不是搜索树
            isSearch = false;//那么就将isSearch修改成false。
        }
        //定义变量leftMaxLessX,即左树的最大值是否小于x的值。
        //如果leftInfo是空,就返回leftMaxLessX是true。否则,就让leftInfo的最大值和x的值真实地比较一下。如果结果是小于,就返回true,否则返回false。
        boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.val);
        //定义变量rightMinMoreX,即右树的最小值是否大于x的值。
        //如果rightMinMoreX是空,就返回rightMinMoreX是true。否则,就让rightInfo的最小值和x的值真实地比较一下。如果结果是大于,就返回true,否则返回false。
        boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > x.val);
        //if (!(leftMaxLessX && rightMinMoreX)) {//如果leftMaxLessX和rightMinMoreX并不都是true,那么整个树就不是搜索树。即将isSearch修改成false。
        if (!leftMaxLessX || !rightMinMoreX) {//如果leftMaxLessX是false,或者rightMinMoreX是false,那么整个树就不是搜索树。即将isSearch修改成false。
            isSearch = false;
        }
        return new Info(isSearch, max, min);//返回Info,包含三个信息。
        //递归对每一个节点一视同仁,所以要构建一个包含三个信息的类(即Info)。你需要返回三个信息,我用哪个信息就调哪个信息,不用的就算了,但是你必须得返回这三个信息。
        //否则,左子树的最大值要小于x的值,和右子树的最小值要大于x的值。这种非通用性的判断条件,会增加编写代码的难度。
    }

    public static Info process(TreeNode x) {
        if (x == null) {
            return null;
        }
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);
        int max = x.val;
        int min = x.val;
        if (leftInfo != null) {
            max = Math.max(leftInfo.max, max);
            min = Math.min(leftInfo.min, min);
        }
        if (rightInfo != null) {
            max = Math.max(rightInfo.max, max);
            min = Math.min(rightInfo.min, min);
        }
        //先定义这个数不是搜索树,后边将搜索树的所有条件都列出来。只有符合所有的条件时,才将isSearch修改成true,否则维持false。
        boolean isSearch = false;
        //如果leftInfo是空,则不违反左子树是搜索树的要求。否则,返回leftInfo的真实情况。是搜索树就返回是;不是就返回不是。
        boolean leftIsBST = leftInfo == null ? true : leftInfo.isSearch;
        //如果rightInfo是空,则不违反右子树是搜索树的要求。否则,返回rightInfo的真实情况。是搜索树就返回是;不是就返回不是。
        boolean rightIsBST = rightInfo == null ? true : rightInfo.isSearch;
        boolean leftMaxLessX = leftInfo == null ? true : leftInfo.max < x.val;//同process()
        boolean rightMinMoreX = rightInfo == null ? true : rightInfo.min > x.val;//同process()
        if (leftIsBST && rightIsBST && leftMaxLessX && rightMinMoreX) {//只有这个4个条件同时满足时,才将isSearch修改成true。否则维持false。
            isSearch = true;
        }
        return new Info(isSearch, max, min);
    }
}

 

posted @ 2022-08-12 22:37  TheFloorIsNotTooHot  阅读(26)  评论(0)    收藏  举报