zoukankan      html  css  js  c++  java
  • 判断二叉树是否BST

    一、问题:

      请实现一个函数,检查一棵二叉树是否为二叉查找树。给定树的根结点指针TreeNode* root,请返回一个bool,代表该树是否为二叉查找树。

    二、思路: 

      解法一:从根节点开始遍历二叉树,其中需要使用到递归进行遍历节点,判断根的左右节点的值与根节点的值的大小的比较,其中递归的思路是假如树有左子树那么我们遍历左子树,有右子树那么遍历右子树,左右子树都有那么我们遍历左右子树,为叶子节点的时候直接返回true即可。除了上面的判断之外还不够,还需要判断左子树中最大的节点值是否小于根节点的值,右子树中最小的节点的值是否大于根节点的值。

      解法二: 首先我们想到的是二叉树中序遍历后的结果是有序的,根据这个结果,我们可以中序遍历二叉树,并把遍历结果存放在一个数组里面,然后判断这个数组大小是否是有序数组,如果是有序数组,则是二叉查找树,否则就不是。  这个方法的时间复杂度是O(N),但是空间复杂度比较高,需要浪费O(N)的存储空间。

    import java.util.ArrayList;
    
    public class CheckBST1 {
        // 中序遍历是否有序
        public boolean checkBST(TreeNode root) {
            if (root == null)
                return false;
            ArrayList<Integer> list = new ArrayList<>();
            inorder(root, list);
            return checkOrdered(list);
        }
    
        // 递归方式把节点按中序遍历顺序加入到列表中
        private void inorder(TreeNode<Integer> node, ArrayList<Integer> list) {
            if (node == null)
                return;
            if (node.left != null) {
                inorder(node.left, list);
            }
            list.add(node.val);
            if (node.right != null) {
                inorder(node.right, list);
            }
        }
    
        // 遍历列表,前后两两比较,如果逆序,返回false
        private boolean checkOrdered(ArrayList<Integer> list) {
            for (int i = 0; i < list.size() - 2; i++) {
                if (list.get(i) > list.get(i + 1))
                    return false;
            }
            return true;
        }
    
        public static class TreeNode<T> {
    
            public T val;
            public TreeNode<T> left = null;
            public TreeNode<T> right = null;
            public TreeNode<T> parent = null;
    
            public TreeNode(T val) {
                this.val = val;
            }
    
        }
    }

      解法三:中序遍历,全局变量记录上一个值,当前值必须大于上一个值。满足条件更新pre为当前值。

     1 public class CheckBST2 {
     2     public boolean checkBST(TreeNode<Integer> root) {
     3         if (root == null)
     4             return true;
     5 
     6         // 检查左子树,如果左子非bst立即返回false
     7         boolean leftIsBST = checkBST(root.left);
     8         if (!leftIsBST)
     9             return false;
    10         // 根的值小于等于左子树的最大值,返回false
    11         if (root.val <= preValue) {
    12             return false;
    13         }
    14         // 更新最后访问的值,检查右子树
    15         preValue = root.val;
    16         return checkBST(root.right);
    17     }
    18 
    19     private int preValue = Integer.MIN_VALUE;
    20 
    21     public static class TreeNode<T> {
    22 
    23         public T val;
    24         public TreeNode<T> left = null;
    25         public TreeNode<T> right = null;
    26         public TreeNode<T> parent = null;
    27 
    28         public TreeNode(T val) {
    29             this.val = val;
    30         }
    31 
    32     }
    33 }
  • 相关阅读:
    全国各地DNS(电信,移动,联通,教育网)
    全国各地电信DNS服务器地址
    免费公共 DNS 大全
    免费公共DNS服务器 全球DNS服务器 国内DNS服务器
    AT指令发送短信
    OpenWrt 定期检测进程是否存在并重启
    OpenWrt 计划任务使用方法
    openwrt-mt7688 修改默认的WIFI SSID
    在MT7628实现wan、wwan与4G动态切换
    Unix常用命令之修改密码
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10408349.html
Copyright © 2011-2022 走看看