备战实习记录之【树与二叉树篇】6——二叉搜索树相关

6 二叉搜索树

6.1 二叉搜索树定义

二叉搜索树有数值「二叉搜索树是一个有序树」

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

  • 它的左、右子树也分别为二叉排序树

6.2 二叉搜索树典型题目

6.2.1 700. 二叉搜索树中的搜索

解法一:递归解法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root==null || root.val==val) return root;
        if(root.val>val){
            return searchBST(root.left,val);
        }
        if(root.val<val){
            return searchBST(root.right,val);
        }
        return null;
    }
}

解法二:迭代解法

对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。

对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。

「对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。」

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root!=null){
            if(root.val<val){
                root = root.right;
            }else if(root.val>val){
                root = root.left;
            }else{
                return root;
            }
        }
        return null;

    }
}

6.2.2 98. 验证二叉搜索树

解法一:

先递归中序遍历将二叉搜索树转变成一个数组。

然后只要比较一下,这个数组是否是有序的,「注意二叉搜索树中不能有重复元素」

class Solution {
    List<Integer> res = new ArrayList<>();
    public boolean isValidBST(TreeNode root) {
        helper(root);
        for(int i=1;i<res.size();i++){
            if(res.get(i)<=res.get(i-1)) return false;
        }
        return true;
    }
    public void helper(TreeNode node){
        if(node==null) return;
        helper(node.left);
        res.add(node.val);
        helper(node.right);
    }
}

解法二:

需要注意:「不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了」

我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点

class Solution {
    public long maxvalue = Long.MIN_VALUE;
    public boolean isValidBST(TreeNode root) {
        if(root==null) return true;
        boolean left = isValidBST(root.left);
        if(maxvalue>=root.val){
            return false;
        }
        maxvalue = root.val;
        boolean right = isValidBST(root.right);
        return left&&right;
    }
}

解法三:

左子树范围的最小值是minVal,最大值是当前节点的值,也就是root的值,因为左子树的值要比当前节点小
右子数范围的最大值是maxVal,最小值是当前节点的值,也就是root的值,因为右子树的值要比当前节点大

class Solution {
    public boolean isValidBST(TreeNode root) {
        return getInfo(root,Long.MIN_VALUE,Long.MAX_VALUE);
        
    }
    public boolean getInfo(TreeNode root,long minval,long maxval){
        if(root==null) return true;
        if(root.val<=minval || root.val>=maxval) return false;
        return getInfo(root.left,minval,root.val)&&getInfo(root.right,root.val,maxval);
    }
}

6.2.3 530. 二叉搜索树的最小绝对差

题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。

「二叉搜索树」是有序的。

遇到在二叉搜索树上求最值、差值之类的,可以理解为在一个有序数组上求最值,求差值,这样就简单多了。

解法一:

最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。

class Solution {
    List<Integer> tmp = new ArrayList<>();
    public int getMinimumDifference(TreeNode root) {
        transfer(root);
        int res = Integer.MAX_VALUE;
        for(int i=1;i<tmp.size();i++){
            int num = Math.abs(tmp.get(i)-tmp.get(i-1));
            if(num<res) res = num;
        }
        return res;

    }
    public void transfer(TreeNode node){
        if(node==null) return;
        transfer(node.left);
        tmp.add(node.val);
        transfer(node.right);
    }
}

解法二:

在解法一的基础上,不需要使用数组进行比对。记录下前一个节点就可以了。

class Solution {
    TreeNode pre ;
    int res = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        transfer2(root);
        return res;

    }
    public void transfer2(TreeNode node){
        if(node==null) return;
        transfer2(node.left);
        if(pre!=null){
            res = Math.min(Math.abs(pre.val-node.val),res);
        }
        pre = node;
        transfer2(node.right);
    }

猜你喜欢

转载自blog.csdn.net/paranior/article/details/115335428
今日推荐