1. BST简介
二叉搜索树的定义(递归定义):
- 节点的左子树包含的节点的值小于该节点的值
- 节点的右子树包含的节点的值大于等于该节点的值
- 节点的左子树和右子树都是BST
2. 基础操作(查、增、删)
//BST由于其定义(左小右大),查找的过程类似于二分查找
public TreeNode searchBST(TreeNode root, int val){
// 根节点为空,或者要查找的值在当前节点
if(root == null || root.val == val) return root;
// 要查找的值小于当前节点,到左子树进行查找
if(val < root.val) return searchBST(root.left);
// 要查找的值大于当前节点,到右子树进行查找
if(val > root.val) return searchBST(root.right);
// 没有查到给定的值
return null;
}
/*
类似BST的查找:
如果 root 是空,则新建树节点作为根节点返回即可。
否则比较 root.val 与目标值的大小关系:
如果 root.val 大于目标值,目标值应当插入root的左子树中;
如果 root.val 小于目标值,目标值应当插入root的右子树中。
*/
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null) return new TreeNode(val);
if(val < root.val) root.left = insertIntoBST(root.left, val);
if(val > root.val) root.right = insertIntoBST(root.right, val);
return root;
}
- 删
删除操作需要记住一点:当左右孩子均存在时,删除该节点的方法是用左子树的最大节点或者右子树的最小节点来替换该节点即可。
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val == key){
//删除当前节点时,有如下三种情况:
//1. 该节点恰好是末端节点,两个子孩子都为空,直接删除;
if(root.left == null && root.right == null) return null;
//2. 该节点只有一个非空子孩子,直接用它替换当前节点;
if(root.left == null) return root.right;
if(root.right == null) return root.left;
//3. 该节点的左右孩子都存在,为了不破坏 BST 的性质,必须找到该节点的左子树中最大的那个节点(左子树中最右的节点),或者右子树中最小的那个节点(右子树中的最左的节点)来替换自己。
if(root.left != null && root.right != null){
// 找到左子树中最大的节点赋值给minNode
TreeNode leftTree = root.left;
TreeNode maxNode = leftTree;
while(leftTree.right!= null){
maxNode= leftTree.right;
}
// 用得到的左子树中最大的节点替换当前要删除的节点
root.val = maxNode.val;
// 替换后要记得删除该minnode
root.left = deleteNode(root.left, maxNode.val);
}
}
else if(key < root.val) root.left = deleteNode(root.left, key);
else if(key> root.val) root.right = deleteNode(root.right ,key);
return root;
}