二叉搜索树---java---黑马

二叉搜索树

get方法实现

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    
    // 查找关键字对应的值
    public Object get(int key) {
        return doGet(root, key);
    }
    
    private Object doGet(BSTNode node, int key) {
        if (node == null) {
            return null;
        }
        if (node.key > key) {
            doGet(node.left, key);	// 向左找
        } else if (node.key < key) {
            doGet(node.right, key);	// 向右找
        } else {
            return node.value;		// 找到
        }
    }
    
    // 非递归方式实现get方法
    public Object get(int key) {
        BSTNode node = root;
        while (node != null) {
            if (node.key < key) {
                node = node.right;
            } else if(node.key > key) {
                node = node.left;
            } else {
                return node.value;
            }
        }
        return null;
    }
}

二叉搜索树,泛型版本

public class BSTTree<T extends Comparable<T>>{
    
    BSTNode<T> root;		// 根节点
    
    static class BSTNode<T>{
        T key;
        object value;
        BSTNode<T> left;
        BSTNode<T> right;
        
        public BSTNode<T>(T key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode<T>(T key, object value, BSTNode<T> left, BSTNode<T> right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    // 非递归方式实现get方法
    public Object get(T key) {
        BSTNode<T> node = root;
        while (node != null) {
            int res = key.compareTo(node.key);
            if (res > 0) {
                node = node.left;
            } else if (res < 0) {
                node = node.right;
            } else {
                return node.value;
            }
        }
        return null;
    }
}

查找最小关键字对应值

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    
    // 查找关键字对应的值
    public Object min() {
        return doMin(root);
    }
    
    private Object doMin(BSTNode node) {
        if (node == null) return null;
        if (node.left == null) {
            return node.value;
        }
        return doMin(BSTNode node.left);
    }
    
    // 非递归方式实现min方法
    public Object min() {
        BSTNode node = root;
        if (node == null) return null;
        while (node.left != null) {
            node = node.left;
        }
        return node.value;
    }
}

put方法实现

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    
    // 实现put方法,未找到则新增,找到则修改
    public void put(int key, Object value) {
        BSTNode node = root;
        BSTNode pre = null;
        if (node == null) return null;
        while (node != null) {
            pre = node;
            if (key < node.key) {
                node = node.left;
            } else if (key > node.key) {
                node = node.right;
            } else {
                node.value = value;
                return;
            }
        }
        if (pre == null) {
            root = new BSTNode(key, value);
            return;
        }
        if (pre.key > key) {
            pre.left = new BSTNode(key, value);
        } else {
            pre.right = new BSTNode(key, value);
        }       
    }
}

前任和后任

找前任

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    public Object predecessor(int key) {
        // 1.节点有左子树,此时左子树中最大值为前任
        // 2.节点无左子树,此时离节点最近、且从左而来的祖先为前任
        BSTNode node = root;
        BSTNode ancestorFromLeft = null;
        while (node != null) {
            if (key < node.key) {
                node = node.left;
            } else if (key > node.key) {
                ancestorFromLeft = node;
                node = node.right;
            } else {
                // 找到该节点
                break;
            }
        }
        // 无节点则返回null
        if (node == null) {
            return null;
        }
        // 1.节点有左子树,此时左子树中最大值为前任
        if(node.left != null) {
            return max(node.left);
        }
        // 2.节点无左子树,此时离节点最近、且从左而来的祖先为前任
        return ancestorFromLeft != null ? ancestorFromLeft.value : null;
    }
    
    public Object max() {
        return max(root);
    }
    
    // 寻找任意节点的最大值
    private Object max(BSTNode node) {
        if (node == null) return null;
        while (node.right != null) {
            node = node.right;
        }
        return node.value;
    }
}

找后任(后继)

在这里插入图片描述
在这里插入图片描述

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    public Object successor(int key) {
        // 寻找该节点是否存在
        BSTNode p = root;
        BSTNode ancestorFromRight = null;
        while (p != null) {
            if (key < p.key) {
                ancestorFromRight = p;
                p = p.left;
            } else if (key > p.key) {
                p = p.right;
            } else {
                break;
            }
        }
        if (p == null) {
            return null;
        }
        // 节点有右子树
        if (p.right != null) {
            return min(p.right);
        }
        // 节点无右子树
        return ancestorFromRight != null ? ancestorFromRight : null;
    }
    
    public Object min() {
        return min(root);
    }
    
    public Object min(BSTNode node) {
        if (node == null) {
            return null;
        } 
        BSTNode p = node;
        while (p.left != null) {
            p = p.left;
        } 
        return p.value;
    }
}

删除操作

在这里插入图片描述

非递归版本

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    // 根据关键字删除节点
    public Object delete(int key) {
        // 寻找该节点是否存在
        BSTNode p = root;
        BSTNode pre = null;
        while (p != null) {
            if (key < p.key) {
                pre = p;
                p = p.left;
            } else if (key > p.key) {
				pre = p;
                p = p.right;
            } else {
                break;
            }
        }
        if(p == null) {
            return null;
        }
        // 删除操作
        if (p.left == null) {
            // 情况1
            shift(pre, p, p.right);
        } else if (p.right == null) {
            // 情况2
            shift(pre, p, p.left);
        } else {
            // 情况4
            // 4.1 被删除节点找后继
            BSTNode node = p.right;
            BSTNode nodeParent = p;		// 后继节点父亲
            while (node.left != null) {
                nodeParent = node;
                node = node.left;
            }
            // 
            if (nodeParent != p) {
                // 删除和后继节点不相邻,处理后继节点后事
                shift(nodeParent, node, node.right);
                node.right = p.right;
            }
            shift(parent, p, node);
            node.left = p.left;
        }
        return p.value;
        
    }
        
    private void shift(BSTNode parent, BSTNode deleted, BSTNode child) {
        if (parent == null) {
            root = child;
        } else if (parent.left == deleted) {
            parent.left = child;
        } else {
            parent.right = child;
        }
        
    }
}

递归版本

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    public Object delete(int key) {
        ArrayList<Object> result = new ArrayList<>();
        root = doDelete(root, key, result);
        return result.isEmpty() ? null : result.get(0);
    }
    
    // 根据关键字删除节点
	public BSTNode doDelete(BSTNode node, int key, ArrayList<Object> result) {
        if (node == null) {
            return null;
        }
        if (key < node.key) {
            node.left = doDelete(node.left, key, result);
        } 
        if (key > node.key) {
            node.right = doDelete(node.right, key, result);
        }
        // 找到被删除节点
        result.add(node.value);
        // 情况1,只有右孩子
        if (node.left == null) {
            return node.right;
        }
        
        // 情况2,只有左孩子
        if (node.right == null) {
            return node.left;
        }
        // 情况3-- 有两个孩子
        BSTNode s = node.right;
        while (s.left != null) {
            s = s.left;
        }
        s.right = doDelete(node.right, s.key, new ArrayList<Object>);
        s.left = node.left;
        return s;
    }
}

范围查询

public class BSTTree{
    
    BSTNode root;		// 根节点
    
    static class BSTNode{
        int key;
        object value;
        BSTNode left;
        BSTNode right;
        
        public BSTNode(int key, object value) {
            this.key = key;
            this.vlaue = value;
        }
        
        public BSTNode(int key, object value, BSTNode left, BSTNode right) {
            this.key = key;
            this.vlaue = value;
            this.left = left;
            this.right = right;
        }
    }
    
    // 找<key的所有value
    public List<Object> less(int key) {
        ArrayList<Object> list = new ArrayList<>();
        Stack<BSTNode> stack = new Stack<>();
        BSTNode p = root;
        while (p != null || !stack.isEmpty()) {
            if (p != null) {
                stack.push(p);
                p = p.left;
            } else {
                BSTNode pop = stack.pop();
                // 处理值
                if (pop.value < key) {
                    list.add(pop.value);
                } else {
                    break;
                }
                p = pop.right;
            }
        }
        return list;
    }
    
    // 找>key的所有value
    public List<Object> greater(int key) {
        ArrayList<Object> list = new ArrayList<>();
        Stack<BSTNode> stack = new Stack<>();
        BSTNode p = root;
        while (p != null || !stack.isEmpty()) {
            if (p != null) {
                stack.push(p);
                p = p.left;
            } else {
                BSTNode pop = stack.pop();
                // 处理值
                if (pop.value > key) {
                    list.add(pop.value);
                }
                p = pop.right;
            }
        }
        return list;
    }
    
    // 找>=key1, && <= key2的所有value
    public List<Object> between(int key1, int key2) {
        ArrayList<Object> list = new ArrayList<>();
        Stack<BSTNode> stack = new Stack<>();
        BSTNode p = root;
        while (p != null || !stack.isEmpty()) {
            if (p != null) {
                stack.push(p);
                p = p.left;
            } else {
                BSTNode pop = stack.pop();
                // 处理值
                if (pop.value < key2 && pop.value > key1) {
                    list.add(pop.value);
                } 
                if (pop.value > key2) break;
                p = pop.right;
            }
        }
        return list;
    }
}

Leetcode

Leetcode701

public class Leetcode701{
    
    public TreeNode insertIntoBST(TreeNode node, int value) {
        if (node == null) {
            return new TreeNode(value);
        }
        if (value < node.value) {
            node.left = insertIntoBST(node.left, int value);
        } 
        if (value > node.right) {
            node.right = insertIntoBST(node.right, int value);
        }
        return node;
    }
}

Leetcode98

判断二叉搜索树是否合法

方法一

采用中序遍历

public class Leetcode98{
    
    public boolean isValidBST(TreeNode node) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode p = node;
        while (p != null || !stack.isEmpty()) {
            if (p != null) {
                stack.push(p);
                p = p.left;
            } else {
                TreeNode pop = stack.pop();
                //
                if (pop.val >= stack.peek()) {
                    return false;
                }
                p = pop.right;
            }
        }
        return true;
    }
}
方法二

中序遍历递归版实现

public class Leetcode98{
    
    long pre = Long.MIN_VALUE;
    
    public boolean isValidBST(TreeNode node) {
        if (node == null) {
            return true;
        }
        boolean a = isValidBST(node.left);
        if(!a) {
            return false;
        }
        // 值
        if (pre >= node.val) {
            return false;
        }
        pre = node.val;
        boolean b = isValidBST(node.right);
        return b;
    }
}
方法三

上下限递归实现

public class Leetcode98 {
    
    public boolean isValidBST(TreeNode root) {
        return doValid(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    
    pubic boolean doValid(TreeNode node, Long min, Long max) {
        if (node == null) {
            return true;
        }
        if (node.val < min || node.val > max) {
            return false;
        }
        return doValid(node.left, min, node.val) && doValid(node.right, node.val, max);
    }
}

Leetcode938

方法一

使用中序遍历

publc class Leetcode938{
    
    public int rangeSumBST(TreeNode root, int low, int high) {
        TreeNode p = root;
        LinkedList<TreeNode> stack = new LinkedList<>();
        int sum = 0;
        while (p!=null || !stack.isEmpty()) {
            if (p!=null) {
                stack.push(p);
                p = p.left;
            }else {
                TreeNode pop = stack.pop();
                if (pop.val > high) {
                    break;
                }
                if (pop.val >= low && pop.val <= high) {
                    sum += pop.val;
                }
                p = pop.right;
            }
        }
        return sum;
    }
}
方法二

使用上下限递归

public class Leetcode938{
    public int rangeSumBST(TreeNode root, int low, int high) {
        return rangeSum(root, low, high);
    }
    
    public int rangeSum(TreeNode node, int low, int high) {
        if (node == null) {
            return 0;
        }
		if (node.val < low) {
            return rangeSum(node.right, low, high);
        }
        if (node.val > high) {
            return rangeSum(node.left, low, high);
        }
        return rangeSumBST(node.left,  low,  high); + rangeSumBST(node.right,  low,  high);
    }
}

Leetcode1008

方法一

非递归版本

public class Leetcode1008{
    public TreeNode bstFromPreorder(int[] nums) {
        TreeNode root = new TreeNode(nums[0]);
        for(int i = 1; i < nums.length; i++) {
            put(root, nums[i]);
        }
        return root;
    }
    
    public void put(TreeNode node, int val) {
        TreeNode pre = null;
        while (node != null) {
            pre = node;
            if (val < node.val) {
                node = node.left;
            } else {
                node = node.right;
            }
        }
        
        if (pre == null) {
            node = new TreeNode(val);
        }
        if (pre.val > val) {
            pre.left = new TreeNode(val);
        } else {
            pre.right = new TreeNode(val);
        }
    }
}
方法二

递归版本

public class Leetcode1008{
    public TreeNode bstFromPreorder(int[] nums) {
        TreeNode root = new TreeNode(nums[0]);
        for(int i = 1; i < nums.length; i++) {
            put(root, nums[i]);
        }
        return root;
    }
    
    public TreeNode put(TreeNode node, int val) {
        if (node == null) {
            return new TreeNode(val);
        }
        if (key < node.val) {
            node.left = put(node.left, val);
        } else if (key > node.val) {
            node.right = put(node.right, val);
        }
        return node;
    }
}
方法三

上下限递归
在这里插入图片描述

public class Leetcode1008{
    public TreeNode bstFromPreorder(int[] nums) {
        return insert(nums, Integer.MAX_VALUE);
    }
    
    int i = 0;
    public TreeNode insert(int[] nums, int max) {
        if (i == nums.length) {
            return null;
        }
        int val = nums[i];
        if (val > max) {
            return null;
        }
        TreeNode node = new TreeNode(val);
        i++;
        node.left = insert(nums, val);
        node.right = insert(nums, max);
        return node;
    }
}
方法四
public class Leetcode1008{
    
    public TreeNode bstFromPreorder(int[] nums) {
        partition(nums, 0, nums.length - 1);
    }
    
    public TreeNode partition(int[] nums, int start, int end) {
        if (start > end) {
            return null;
        }
        TreeNode root = new TreeNode(nums[start]);
        int index = start + 1;
        while (index <= end) {
            if (nums[index] > nums[start]) {
                break;
            }
            index++;
        }
        root.left = partition(nums, start + 1, index - 1);
        root.right = partition(nums, index, end);
        return root;
    }
}

Leetcode235

二叉树最近公共祖先

public class Leetcode235 {
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode a = root;
        while ((a.val < p.val && a.val < q.val) || (a.val > p.val && a.val > q.val)) {
            if (a.val < p.val) {
                a = a.left;
            } else {
                a = a.right;
            }

        }
        return a;
    }
}

(start > end) {
return null;
}
TreeNode root = new TreeNode(nums[start]);
int index = start + 1;
while (index <= end) {
if (nums[index] > nums[start]) {
break;
}
index++;
}
root.left = partition(nums, start + 1, index - 1);
root.right = partition(nums, index, end);
return root;
}
}


### Leetcode235

二叉树最近公共祖先

```java
public class Leetcode235 {
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        TreeNode a = root;
        while ((a.val < p.val && a.val < q.val) || (a.val > p.val && a.val > q.val)) {
            if (a.val < p.val) {
                a = a.left;
            } else {
                a = a.right;
            }

        }
        return a;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值