class BST<Key extends Comparable<Key>, Value>{
private Node root;
private class Node{
private Key key;
private Value val;
private Node left, right;
private int N;
public Node(Key key, Value val, int N){
this.key = key;
this.val = val;
this.N = N;
}
}
public int size(){
return size(root);
}
private int size(Node x){
if(x == null) return 0;
else return x.N;
}
public Value get(Key key){
return get(root, key);
}
private Value get(Node x, Key key){
if(x == null) return null;
int cmp = key.compareTo(x.key);
if(cmp < 0) return get(x.left, key);
if(cmp > 0) return get(x.right, key);
else return x.val;
}
public void put(Key key, Value value){
root = put(root, key, value);
}
private Node put(Node x, Key key, Value val){
if(x == null) return new Node(key, val, 1);
int cmp = key.compareTo(x.key);
if(cmp < 0) x.left = put(x.left, key, val); //更新
else if(cmp > 0) x.right = put(x.right, key, val);
else x.val = val;
x.N = size(x.left) + size(x.left) + 1; //更新
return x;
}
public Key min(){
return min(root).key;
}
private Node min(Node x){
if(x.left == null) return x;
return min(x.left);
}
public Key floor(Key key){
Node x = floor(root ,key);
if( x == null) return null;
return x.key;
}
private Node floor(Node x, Key key){
if(x == null) return null;
int cmp = key.compareTo(x.key);
if(cmp == 0) return x;
if(cmp < 0) return floor(x.left, key);
Node t = floor(x.right, key);
if (t != null ) return t;
else return x;
}
public void deleteMin(){
root = deleteMin(root);
}
private Node deleteMin(Node x){
if(x.left == null) return x.right;
x.left = deleteMin(x.left);
x.N = size(x.left) + size(x.right) + 1;
return x;
}
public void delete(Key key){
root = delete(root, key);
}
private Node delete(Node x, Key key){
if(x == null) return null;
int cmp = key.compareTo(x.key);
if(cmp < 0) x.left = delete(x.left, key);
else if(cmp > 0) x.right = delete(x.right, key);
else {
if(x.right == null) return x.left;
if(x.left == null) return x.right;
Node t = x; //删除的节点有左右孩子
x = min(t.right);
x.right = deleteMin(t.right);
x.left = t.left;
}
x.N = size(x.left) + size(x.right) + 1;
return x;
}
}
对于二叉查找树,删除一个节点时,当这个节点没有左右孩子时,或者只有左孩子或右孩子时,删除比较简单,当这个节点有左右两个孩子时,删除需要4个步骤,假设要删除的节点为x:
1.将指向即将被删除的节点的连接保存为t,即t=x
2.将x指向它左孩子树中的最小一个节点 ,即x=min(t.min)
3.将x的右连接(原本指向一棵所有节点都大于x.key的二叉查找树)指向deleteMin(t.right),也就是在删除后所有节点仍然都大于x.key的子二叉查找树
4.将x的左链接(本为空)设为t.left(其下所有的键都小于被删除的节点和它的后继节点)