目录
1.概念
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树
:
例如:
2.功能
先建立一棵树。
public class MyBST {
//先实现一棵树
private TreeNode root;
private int size;
private static class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
}
2.1查找元素
2.1.1查找最大值
二叉搜索树的最大值一定在最右边。
//查找最大值
public int max(){
if(size==0){
throw new NoSuchElementException("tree is empty");
}
TreeNode maxNode=findMaxNode(root);
return maxNode.val;
}
private TreeNode findMaxNode(TreeNode root) {
if(root.right==null){
return root;
}
return findMaxNode(root.right);
}
2.1.2查找最小值
二叉搜索树的最小值一定在最左边。
//查找最小值
public int min() {
if (size == 0) {
throw new NoSuchElementException("tree is empty");
}
TreeNode minNode=findMinNode(root);
return minNode.val;
}
private TreeNode findMinNode(TreeNode root) {
if(root.left==null){
return root;
}
return findMinNode(root.left);
}
2.2添加元素
根据节点值元素的大小,判断在哪里添加元素。
//添加元素
public void add(int val){
root=add(root,val);
}
private TreeNode add(TreeNode root,int val){
if(root==null){
TreeNode node=new TreeNode(val);
size++;
return node;
}else if(root.val<val){
root.right=add(root.right,val);
return root;
}
root.left=add(root.left,val);
return root;
}
2.3删除元素
2.3.1删除最大值
先找到最大值所在的节点(即最右边的节点)
如果最大值有左孩子,则删除最大值后左孩子就变为新的最大值。返回新节点。
如果没有左孩子,则直接返回删除后的新节点。
//删除最大值
public int removeMax(){
//先找到最大值所在的节点
TreeNode maxNode=findMaxNode(root);
//将root更新为删除后的root
root=removeMax(root);
return maxNode.val;
}
//在以root为根节点的BST中,删除最大值的节点,返回删除后的根节点
private TreeNode removeMax(TreeNode root){
if(size==0){
throw new NoSuchElementException("tree is empty");
}
if(root.right==null){
//此时root就是最大值节点
TreeNode left=root.left;
//将右孩子放到根节点上,同时将根节点变为叶子节点
root.left=root=null;
size--;
return left;
}
//此时继续在右子树中删除节点
root.right=removeMax(root.right);
return root;
}
2.3.2删除最小值
先找到最小值所在的节点(即最左边的节点)
如果最小值有右孩子,则删除最小值后右孩子就变为新的最大值。返回新节点。
如果没有右孩子,则直接返回删除后的新节点。
//删除最小值
public int removeMin(){
TreeNode minNode=findMinNode(root);
root=removeMin(root);
return minNode.val;
}
private TreeNode removeMin(TreeNode root){
if(root.left==null){
TreeNode right=root.right;
root.right=root=null;
size--;
return right;
}
root.left=removeMin(root.left);
return root;
}
2.3.3删除任意节点
先找到值为val的节点。有三种情况:
1.此节点为最大值节点,使用removeMax()方法
2.此节点为最小值节点,使用removeMin()方法
3.此节点为除最大最小值节点的其它节点
当为第三种情况时。
例如下图:要删除值为15的节点。需要移动一个节点到被删除节点的位置上来。
此节点需要满足:
以此节点为根的左子树上的值都小于根节点的值,右子树上的值都大于根节点的值。
那么纵观全图,有两个节点合适。即14和18。
这里我们以右子树上的18来写代码。
//删除值为val的节点
public void remove(int val){
remove(root,val);
}
//在以root为根的BST中删除值为val的节点,返回删除后的树根节点
private TreeNode remove(TreeNode root,int val){
//先找到值为val的节点在哪里
if(root==null){
//递归到叶子节点,还是没有找到值为val的节点
return null;
}else if(val<root.val){
root.left=remove(root.left,val);
return root;
}else if(val>root.val){
root.right=remove(root.right,val);
return root;
}else{
//找到了值val所在的节点
//此节点为最大值节点时
if(root.right==null){
TreeNode left=root.left;
root.left=root=null;
size--;
return left;
//此节点为最小值节点时
}else if(root.left==null){
TreeNode right=root.right;
root.right=root=null;
size--;
return right;
}
//此时左右子树都不为空
//右子树最小值
TreeNode successor=findMinNode(root.right);
successor.right=removeMin(root.right);
successor.left=root.left;
root.left=root.right=root=null;
return successor;
}
}