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(其下所有的键都小于被删除的节点和它的后继节点)