有序二叉树的中序遍历就是一个单调递增的数组!!!

搜索一条边的写法:

  1. if (递归函数(root->left)) return ;
  2. if (递归函数(root->right)) return ;

搜索整个树写法:

left = 递归函数(root->left);
right = 递归函数(root->right);
left与right的逻辑处理;

labuladong 题解思路

700. 二叉搜索树中的搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) {
            return null;
        }

        //单层逻辑
        if (root.val > val) {
            return searchBST(root.left, val);
        }
        if (root.val < val) {
            return searchBST(root.right, val);
        }
        return root;
    }
}

98. 验证二叉搜索树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
 //中序遍历
class Solution {
    TreeNode pre = null;//前一个节点
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;

        boolean left = isValidBST(root.left);//前
        if (pre != null && pre.val >= root.val){//中
            return false;
        }
        pre = root;// 更新前一个节点
        boolean right = isValidBST(root.right);//右
        return left && right;
    }
}

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

那么二叉搜索树采用中序遍历,其实就是一个有序数组。
在一个有序数组上求两个数最小差值,这是不是就是一道送分题了。
image.png

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode pre = null;//前驱
    int result = Integer.MAX_VALUE;
    private void traversal(TreeNode root){
        if (root == null) return;
        traversal(root.left);//左
        if (pre != null){
            result = Math.min(result,root.val - pre.val);//中
        }
        pre = root;//前驱赋值
        traversal(root.right);//右
    }


    public int getMinimumDifference(TreeNode root) {
        traversal(root);
        return result;
    }
}

501. 二叉搜索树中的众数

暴力法

class Solution {
    public int[] findMode(FindModeInBinarySearchTree.TreeNode root) {
        Map<Integer, Integer> map = new HashMap<>();
        List<Integer> list = new ArrayList<>();
        if (root == null) return list.stream().mapToInt(Integer::intValue).toArray();
        // 获得频率 Map
        searchBST(root, map);
        List<Map.Entry<Integer, Integer>> mapList = map.entrySet().stream()
                .sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue()))
                .collect(Collectors.toList());
        list.add(mapList.get(0).getKey());
        // 把频率最高的加入 list
        for (int i = 1; i < mapList.size(); i++) {
            if (mapList.get(i).getValue() == mapList.get(i - 1).getValue()) {
                list.add(mapList.get(i).getKey());
            } else {
                break;
            }
        }
        return list.stream().mapToInt(Integer::intValue).toArray();
    }

    void searchBST(FindModeInBinarySearchTree.TreeNode curr, Map<Integer, Integer> map) {
        if (curr == null) return;
        map.put(curr.val, map.getOrDefault(curr.val, 0) + 1);
        searchBST(curr.left, map);
        searchBST(curr.right, map);
    }

}

搜索二叉树中序遍历有序特性来写

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    List<Integer> result = new ArrayList<>();
    int maxCount;//最大频率
    int count;//统计频率
    TreeNode pre;//前驱
    private void searchBST(TreeNode cur){
        if (cur == null) return;

        searchBST(cur.left);//左
        if (pre == null){//说明是第一个节点
            count = 1;
        }else if (pre.val == cur.val){//与前一个节点值相同
            count++;
        }else {//与前一个节点值不相同
            count = 1;//重置
        }
        pre = cur;//更新前驱

        if (count == maxCount){//如果和最大值相同,则刚入result
            result.add(cur.val);
        }
        if (count > maxCount){//如果计数大于最大频率
            maxCount = count;//更新
            result.clear();//清除result,因为现在最大的已经不是之前的max了
            result.add(cur.val);
        }
        searchBST(cur.right);//右
    }

    public int[] findMode(TreeNode root) {
        searchBST(root);
        int[] res = new int[result.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = result.get(i);
        }
        return res;
    }
}

236. 二叉树的最近公共祖先

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) { // 递归结束条件
            return root;
        }

        // 后序遍历
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left == null && right == null) { // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null) { // 若找到一个节点
            return right;
        }else if(left != null && right == null) { // 若找到一个节点
            return left;
        }else { // 若找到两个节点
            return root;
        }
    }
}

235. 二叉搜索树的最近公共祖先

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    private TreeNode traversal(TreeNode cur,TreeNode p,TreeNode q){
        //终止条件
        if (cur == null) return cur;
        //单层递归
        if (cur.val > p.val && cur.val > q.val){//都在左子树
            TreeNode left = traversal(cur.left, p, q);
            if (left != null){
                return left;
            }
        }else if (cur.val < p.val && cur.val < q.val){//都在右子树
            TreeNode right = traversal(cur.right, p, q);
            if (right != null){
                return right;
            }
        }else {
            return cur;//在两棵子树
        }
        return cur;
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return traversal(root,p,q);
    }
}

701. 二叉搜索树中的插入操作

其实就是在空姐点插入val根本不需要改变树形

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        //终止条件
        // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
        if (root == null){
            TreeNode node = new TreeNode(val);
            return node;
        }
        //单层递归逻辑

        if (root.val > val){
            //// 递归创建左子树
            root.left = insertIntoBST(root.left, val);
        }
        if (root.val < val){
            //// 递归创建右子树
            root.right = insertIntoBST(root.right, val);
        }
        return root;
    }
}

450. 删除二叉搜索树中的节点

这就涉及改变树形状了

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
     public TreeNode deleteNode(TreeNode root, int key) {
        //终止条件
        if (root == null) return root;
        if (root.val == key){//找到节点
            //左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
            if (root.left == null && root.right == null){
                return null;
            }else if (root.left == null && root.right != null){//左为空,右不为空 返回root。right
                return root.right;
            }else if (root.left != null && root.right == null){//左bu为空,右为空 返回root。left
                return root.left;
            }else if (root.left != null && root.right != null){
                TreeNode cur = root.right;
                while (cur.left != null){
                    cur = cur.left;
                }
                cur.left = root.left;
                return root.right;
            }
        }
        if (root.val > key){
            root.left = deleteNode(root.left,key);
        }
        if (root.val < key){
            root.right = deleteNode(root.right,key);
        }
        return root;
    }
}

669. 修剪二叉搜索树

https://www.programmercarl.com/0669.%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html#递归法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    // 定义:删除 BST 中小于 low 和大于 high 的所有节点,返回结果 BST
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) return null;

        if (root.val < low) {
            // 直接返回 root.right
            // 等于删除 root 以及 root 的左子树
            return trimBST(root.right, low, high);
        }
        if (root.val > high) {
            // 直接返回 root.left
            // 等于删除 root 以及 root 的右子树
            return trimBST(root.left, low, high);
        }

        //接下来要将上一层处理完左子树的结果赋给root->left,
        //处理完右子树的结果赋给root->right。
        //最后返回root节点,代码如下:
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);

        return root;
    }
}

538. 把二叉搜索树转换为累加树

class Solution {
    public TreeNode convertBST(TreeNode root) {
        traverse(root);
        return root;
    }

    // 记录累加和
    int sum = 0;
    void traverse(TreeNode root) {
        if (root == null) {
            return;
        }
        traverse(root.right);
        // 维护累加和
        sum += root.val;
        // 将 BST 转化成累加树
        root.val = sum;
        traverse(root.left);
    }
}
// 详细解析参见:
// https://labuladong.github.io/article/?qno=538