基本概念
什么叫二叉搜索树?
1、树节点增加key属性,用来比较谁大谁小,key不可以重复
2、对于任意一个树节点,它的key比左子树的key都大,同时也比右子树的key都小
最优情况的二叉搜索树是左右子树差不多平衡,时间复杂度为O(logn)
最差的情况是左右子树少了一边,又变成线性结构,此时时间复杂度为O(n)
算法实现
这里真的学了好久,也学了好多东西,停滞了好久哈哈哈,我把一些重要的贴上来
存储关键字和对应值(新增)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 
 | 
 
 
 
 public void put(int key, Object value) {
 
 BSTNode node = root;
 
 BSTNode parent = null;
 while(node != null) {
 parent = node;
 if (node.key < key) {
 
 node = node.left;
 } else if (node.key > key) {
 
 node = node.right;
 } else {
 
 node.value = value;
 
 return;
 }
 }
 
 if(parent == null) {
 root = new BSTNode(key, value);
 return;
 }
 if(key < parent.key) {
 
 parent.left = new BSTNode(key, value);
 } else {
 
 parent.right = new BSTNode(key, value);
 }
 }
 
 | 
找二叉搜索树前任
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | 
 
 
 
 public Object successor(int key) {
 BSTNode p = root;
 
 BSTNode ancestorFromLeft = null;
 while(p != null) {
 if(key < p.key) {
 p = p.left;
 } else if (key > p.key) {
 ancestorFromLeft = p;
 p = p.right;
 } else {
 break;
 }
 }
 
 if(p == null) {
 return null;
 }
 
 if(p.left != null) {
 return max(p.left);
 }
 
 return ancestorFromLeft != null ? ancestorFromLeft.value : null;
 }
 
 | 
找二叉搜索树后继
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | 
 
 
 
 public Object predecessor(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 getMin2(p.right);
 }
 
 return ancestorFromRight != null ? ancestorFromRight.value : null;
 }
 
 | 
根据关键字删除(非递归递归)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 
 | 
 
 
 
 public Object delete(int key) {
 BSTNode p = root;
 BSTNode parent = null;
 while(p != null) {
 if(key < p.key) {
 parent = p;
 p = p.left;
 } else if (key > p.key) {
 parent = p;
 p = p.right;
 } else {
 break;
 }
 }
 
 if(p == null) {
 return null;
 }
 
 if(p.left == null) {
 
 shift(parent, p, p.right);
 } else if(p.right == null) {
 
 shift(parent, p, p.left);
 } else {
 
 
 BSTNode s = p.right;
 BSTNode sParent = p;
 while(s.left != null) {
 sParent = s;
 s = s.left;
 }
 
 
 if(sParent != p) {
 
 shift(sParent, s, s.right);
 s.right = p.right;
 }
 
 shift(parent, p, s);
 s.left = p.left;
 }
 return p.value;
 }
 
 
 
 
 
 
 
 private void shift(BSTNode parent, BSTNode deleted, BSTNode child) {
 
 if(parent == null) {
 
 root = child;
 } else if (deleted == parent.left) {
 parent.left = child;
 } else if (deleted == parent.right) {
 parent.right = child;
 }
 }
 
 | 
递归版本
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | 
 
 
 
 
 private BSTNode doDelete(BSTNode node, int key) {
 if(node == null) {
 return null;
 }
 if(key < node.key) {
 node.left = doDelete(node.left, key);
 return node;
 }
 if(node.key < key) {
 node.right = doDelete(node.right, key);
 return node;
 }
 
 if(node.left == null) {
 return node.right;
 }
 
 if(node.right == null) {
 return node.left;
 }
 
 BSTNode s = node.right;
 while(s.left != null) {
 s = s.left;
 }
 
 doDelete(s.right, s.key);
 s.left = node.left;
 return s;
 }
 
 | 
根据关键字范围查询
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | 
 
 
 
 
 public List<Object> between(int key1 , int key2) {
 
 ArrayList<Object> result = new ArrayList<>();
 
 BSTNode p = root;
 
 LinkedList<BSTNode> stack = new LinkedList<>();
 while (p != null || stack.isEmpty()) {
 if(p != null) {
 stack.push(p);
 p = p.left;
 } else {
 
 BSTNode pop = stack.pop();
 
 if(key1 >= pop.key && key2 <= pop.key) {
 result.add(pop.value);
 } else if (pop.key > key2) {
 break;
 }
 
 p = pop.right;
 }
 }
 return result;
 }
 
 | 
力扣题目合集
力扣450-删除节点
见力扣上代码哈哈哈
力扣701-新增节点
递归版本
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | public TreeNode insertIntoBST(TreeNode root, int val) {
 if(root == null) {
 
 return new TreeNode(val);
 }
 if(root.val < val) {
 
 root.right = insertIntoBST(root.right, val);
 } else {
 
 root.left = insertIntoBST(root.left, val);
 }
 return root;
 }
 
 | 
力扣700-查询节点
递归版本
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | public TreeNode searchBST(TreeNode root, int val) {
 if(root == null) {
 return null;
 }
 if(val < root.val) {
 return searchBST(root.left, val);
 } else if(val > root.val) {
 return searchBST(root.right, val);
 } else {
 return root;
 }
 }
 
 | 
力扣98-验证合法二叉搜索树
简单的方法就是中序遍历如果是升序的那么就是合法的
下面的是递归剪枝方法,很牛
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | long prev = Long.MIN_VALUE;
 public boolean isValidBST(TreeNode root) {
 
 if(root == null) {
 return true;
 }
 
 boolean a = isValidBST(root.left);
 
 
 if(!a) {
 return false;
 }
 
 if(prev >= root.val) {
 return false;
 }
 prev = root.val;
 return isValidBST(root.right);
 }
 
 | 
力扣938-二叉搜索树范围和
还是d递归剪枝方法,其它方法都很简单
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | public int rangeSumBST(TreeNode root, int low, int high) {
 if(root == null) {
 return 0;
 }
 if(root.val < low) {
 
 return rangeSumBST(root.right, low, high);
 }
 if(root.val > high) {
 
 return rangeSumBST(root.left, low, high);
 }
 
 return root.val + rangeSumBST(root.left, low, high) + rangeSumBST(root.right, low, high);
 }
 
 | 
力扣1008-前序遍历构造二叉搜索树
递归分而治之法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 |  public TreeNode bstFromPreorder(int[] preorder) {
 return fenerzhizhi(preorder, 0, preorder.length - 1);
 }
 private TreeNode fenerzhizhi(int[] preorder, int start, int end) {
 if(start > end) {
 
 return null;
 }
 
 TreeNode root = new TreeNode(preorder[start]);
 int index = start + 1;
 while(index <= end) {
 if(preorder[start] < preorder[index]) {
 break;
 }
 index++;
 }
 
 root.left = fenerzhizhi(preorder, start + 1, index - 1);
 root.right = fenerzhizhi(preorder, index, end);
 return root;
 }
 
 | 
力扣235-二叉搜索树最近公共祖先
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | 待查找点p q 在某一个结点的两侧,那么此节点就是最近的公共祖先public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
 
 TreeNode a = root;
 while(p.val < a.val && q.val < a.val || p.val > a.val && q.val > a.val) {
 
 if(p.val < a.val) {
 a = a.left;
 } else {
 a = a.right;
 }
 }
 return a;
 }
 
 |