• 如何判断一颗二叉树是否是搜索二叉树


    什么是搜索二叉树?

    可知,如果对二叉搜索树进行中序排列(左中右),那么会得到一个从小到大的序列。

     因此,如果用中序遍历搜索二叉树,肯定是一个升序的过程

    判断一颗二叉树是否是搜索二叉树可以用中序遍历(递归/非递归)代码进行改写 

    package Algorithms.tree;
    
    import java.util.LinkedList;
    import java.util.Stack;
    
    public class IsBST {
    
        public static void main(String[] args) {
            Node head = new Node(10);
            head.left = new Node(8);
            head.right = new Node(15);
            head.left.left = new Node(5);
            head.left.right = new Node(9);
            head.right.right = new Node(17);
            head.left.left.right = new Node(6);
            head.right.right.left = new Node(16);
    
            System.out.println(isBST1(head)); //true
            System.out.println(isBST2(head)); //true
            System.out.println(isBST3(head)); //true
            System.out.println(isBST(head)); //true
        }
    
        public static class Node {
            public int value;
            public Node left;
            public Node right;
    
            public Node(int data) {
                this.value = data;
            }
        }
    
        public static int preValue = Integer.MIN_VALUE;
    
        //方式1:递归动态遍历比较(中序递归遍历代码改写)
        public static boolean isBST1(Node head) {
            if (head == null) { //空树,是搜索二叉树
                return true;
            }
            boolean isLeftBST = isBST1(head.left); //检查左数是不是搜索二叉树
            if (!isLeftBST) {
                return false;
            }
            //由打印变成比较
            if (head.value <= preValue) {
                return false;
            } else {
                preValue = head.value;
            }
            return isBST1(head.right); //进行上面操作之后,如果右树是搜索二叉树那就返回true
        }
    
        //方式2:中序遍历添加到LinkedList中,再for循环遍历比较
        public static boolean isBST2(Node head) {
            if (head == null) {
                return true;
            }
            LinkedList<Node> inOrderList = new LinkedList<>(); //用来存中序遍历的Node
            process(head, inOrderList);
            int pre = Integer.MIN_VALUE; //记录上一次处理的数
            for (Node cur : inOrderList) {
                if (cur.value <= pre) {
                    return false;
                }
                pre = cur.value;
            }
            return true;
        }
    
        //中序遍历二叉树,把遍历的结果放在inOrderList中
        public static void process(Node node, LinkedList<Node> inOrderList) {
            if (node == null) {
                return;
            }
            process(node.left, inOrderList);
            inOrderList.add(node);
            process(node.right, inOrderList);
        }
    
        //方式3:非递归
        public static boolean isBST3(Node head) {
            if (head != null) {
                int preValue = Integer.MIN_VALUE;
                Stack<Node> stack = new Stack<Node>();
                while (!stack.isEmpty() || head != null) {
                    if (head != null) { //1、把当前节点所有的左节点压栈
                        stack.push(head);
                        head = head.left;
                    } else { //所有左节点压栈之后
                        head = stack.pop(); //2、弹出一个节点,比较
                        if (head.value <= preValue) {
                            return false;
                        } else {
                            preValue = head.value;
                        }
                        head = head.right; //3、然后移动到弹出节点的右节点上面,循环以上步骤
                    }
                }
            }
            return true;
        }
    
        //方式4:递归处理二叉树的套路来判断是否为搜索二叉树(树型DP)
        //如果是搜索二叉树(头节点head),要满足:
        //1、左子树是二叉树
        //2、右子树是二叉树
        //3、左子树的最大值max < head.value
        //4、右子树的最小值min > head.value
        //使用递归完成的话左右子树的要求得一样,但条件3/4明显有冲突,
               //因此我们一律返回三个要素:当前树是否为搜索二叉树、当前树的最大值与最小值
    
        //定义返回值的类型
        public static class ReturnData {
            public boolean isBST;
            public int min;
            public int max;
    
            public ReturnData(boolean isBST, int min, int max) {
                this.isBST = isBST;
                this.min = min;
                this.max = max;
            }
        }
    
        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, leftData.max);
            }
            if (rightData != null) {
                min = Math.min(min, rightData.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;
            }
    
    //        boolean isBST = false;
    //        if (
    //                (leftData!=null?(leftData.isBST && leftData.max <x.value):true)&&
    //                        (rightData!=null?(rightData.isBST && rightData.min>x.value):true)
    //        ){
    //            isBST = true;
    //        }
            return new ReturnData(isBST, min, max);
        }
    
        //主函数
        public static boolean isBST(Node head) {
            return process(head).isBST;
        }
    
    }

     

  • 相关阅读:
    20165204 Java第五周学习总结
    20165204Java第四周学习
    20165204Java第四周课上补做
    20175213 2018-2019-2 《Java程序设计》第6周学习总结
    类定义(课下选做) 20175213
    2018-2019-2 20175213实验一 《Java开发环境的熟悉》实验报告
    20175213 2018-2019-2 《Java程序设计》第4周学习总结
    # 20175213 2018-2019-2 《Java程序设计》第1周学习总结
    # 20175213 2018-2019-2 《Java程序设计》第2周学习总结
    20175213 2018-2019-2 《Java程序设计》第3周学习总结
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15132211.html
Copyright © 2020-2023  润新知