自平衡的插入删除,无论按什么顺序插入,得到的都是一棵平衡树。删除任意结点之后也保持平衡性。
经典的LL,RR, LR,RL那种旋转方法。注意旋转操作的特点,例如右旋,新root原来的右子树从原来属于左子树,变成属于右子树,要保证这棵移动到另一边的树是其父节点两棵子树中较小的那棵。
public class AVLTreeMap<Key extends Comparable<Key>, Value> {
private class TreeNode {
Key key;
Value value;
TreeNode left, right;
int ht, sz;
TreeNode(Key k, Value v) {
this.key = k;
this.value = v;
this.ht = 1;
this.sz = 1;
}
}
private TreeNode root;
private int height(TreeNode root) {
if (root == null) return 0;
return root.ht;
}
private int size(TreeNode root) {
if (root == null) return 0;
return root.sz;
}
private void update(TreeNode root) {
root.sz = size(root.left) + size(root.right) + 1;
root.ht = Math.max(height(root.left), height(root.right)) + 1;
}
private TreeNode rotateRight(TreeNode root) {
TreeNode l = root.left;
root.left = l.right;
update(root);
l.right = root;
update(l);
return l;
}
private TreeNode rotateLeft(TreeNode root) {
TreeNode r = root.right;
root.right = r.left;
update(root);
r.left = root;
update(r);
return r;
}
private TreeNode balance(TreeNode root) {
if (height(root.left) - height(root.right) > 1) {
if (height(root.left.left) > height(root.left.right)) { //LL
root = rotateRight(root);
}
else { //LR
root.left = rotateLeft(root.left);
root = rotateRight(root);
}
}
else if (height(root.right) - height(root.left) > 1) {
if (height(root.right.right) > height(root.right.left)) { //RR
root = rotateLeft(root);
}
else { //RL
root.right = rotateRight(root.right);
root = rotateLeft(root);
}
}
return root;
}
private TreeNode put(TreeNode root, Key key, Value value) {
if (root == null) return new TreeNode(key, value);
if (key.compareTo(root.key) < 0) root.left = put(root.left, key, value);
else if (key.compareTo(root.key) > 0) root.right = put(root.right, key, value);
else root.value = value;
update(root);
return balance(root);
}
public void put(Key key, Value value) {
root = put(root, key, value);
}
private TreeNode min(TreeNode root) {
if (root.left == null) return root;
return min(root.left);
}
private TreeNode remove(TreeNode root, Key key) {
if (root == null) return null;
if (key.compareTo(root.key) < 0) {
root.left = remove(root.left, key);
}
else if (key.compareTo(root.key) > 0) {
root.right = remove(root.right, key);
}
else {
if (root.left == null) return root.right;
else if (root.right == null) return root.left;
else {
TreeNode successor = min(root.right);
Key tempKey = root.key;
root.key = successor.key;
root.value = successor.value;
successor.key = tempKey;
root.right = remove(root.right, tempKey);
}
}
update(root);
return balance(root);
}
public void remove(Key key) {
remove(root, key);
}
private int rank(TreeNode root, Key key) {
if (root == null) return 0;
if (key.compareTo(root.key) == 0) return size(root.left);
if (key.compareTo(root.key) < 0) return rank(root.left, key);
return size(root.left) + 1 + rank(root.right, key);
}
public int rank(Key key) {
return rank(root, key);
}
private TreeNode select(TreeNode root, int rank) {
if (root == null) return null;
if (rank == size(root.left)) return root;
if (rank < size(root.left)) return select(root.left, rank);
return select(root.right, rank - size(root.left) - 1);
}
public Key select(int rank) {
TreeNode x = select(root, rank);
if (x == null) return null;
return x.key;
}
private TreeNode floor(TreeNode root, Key key) {
if (root == null) return null;
int cmp = key.compareTo(root.key);
if (cmp == 0) return root;
if (cmp < 0) return floor(root.left, key);
TreeNode f = floor(root.right, key);
if (f == null) return root;
return f;
}
public Key floor(Key key) {
TreeNode f = floor(root, key);
if (f == null) return null;
return f.key;
}
private TreeNode ceiling(TreeNode root, Key key) {
if (root == null) return null;
int cmp = key.compareTo(root.key);
if (cmp == 0) return root;
if (cmp > 0) return ceiling(root.right, key);
TreeNode ceil = ceiling(root.left, key);
if (ceil == null) return root;
return ceil;
}
public Key ceiling(Key key) {
TreeNode x = ceiling(root, key);
if (x == null) return null;
return x.key;
}
}