/**
* 为了 看了行出些 就不写树堆那样的 结构了。 虽然操作 方便些。
*/
public class AVLTree<Key extends Comparable<Key>, Value> {
private class Node {
private final Key key;
private Value val;
private int height;
private int size;
private Node left;
private Node right;
public Node(Key key, Value val, int height, int size) {
this.key = key;
this.val = val;
this.size = size;
this.height = height;
}
}
private Node root;
public AVLTree() {
}
public void insert(Key key, Value value) {
if (key == null) throw new IllegalArgumentException("key is null");
if (value == null) {
// todo delete
return;
}
root = insert(root, key, value);
}
private Node insert(Node x, Key key, Value value) {
if (x == null) return new Node(key, value, 0, 1);
int cmp = key.compareTo(x.key);
if (cmp < 0) {
x.left = insert(x.left, key, value);
} else if (cmp > 0) {
x.right = insert(x.right, key, value);
} else {
x.val = value;
return x;
}
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
return balance(x);
}
/**
*
* @param key
* @return
*
*/
public Value delete(Key key) {
if (key == null) throw new IllegalArgumentException("delete key is null");
Tuple<Node, Value> ans = delete(root, key);
root = ans.first;
return ans.second;
}
private Tuple<Node, Value> delete(Node x, Key key) {
Tuple<Node, Value> it = null;
Value tmp = null;
int cmp = key.compareTo(x.key);
if (cmp < 0) {
it = delete(x.left, key);
x.left = it.first;
} else if (cmp > 0) {
it = delete(x.right, key);
x.right =it.first;
} else {// 就是这个点
tmp = x.val;
if (x.left == null) {
return new Tuple<>(x.right, x.val);
}
if (x.right == null) {
return new Tuple<>(x.left, x.val);
}
// 递归删除节点
Node y = x;
x = min(y.right); // 比原值大的最小节点
x.right = deleteMin(y.right); // 因为吧那个节点上调,所以递归性质的删除那个节点
x.left = y.left;
}
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
Node node = balance(x);
if (it != null) {
return new Tuple<>(node, it.second);
} else {
return new Tuple<>(node, tmp);
}
}
public Value query(Key value) {
return query(root, value);
}
private Value query(Node node, Key key) {
if(node == null) return null;
int cmp = key.compareTo(node.key);
if (cmp == 0) {
return node.val;
}
if (cmp < 0) {
return query(node.left, key);
} else {
return query(node.right, key);
}
}
private void rangeQuery(Node node, Key left, Key right, Queue<Value> ans) {
if (node == null) return;
int cmpl = left.compareTo(node.key);
int cmpr = right.compareTo(node.key);
if (cmpl < 0) rangeQuery(node.left, left, right, ans);
if (cmpl <= 0 && cmpr >= 0)
ans.add(node.val);
if (cmpr > 0) rangeQuery(node.right, left, right, ans);
}
/**
* ------------------ 工具函数 ---------------------
**/
private Node balance(Node x) {
int tmp = balanceCheck(x);
// 高度差超过1
if (tmp < -1) { // 右边深度大
if (balanceCheck(x.right) > 0) { // 调整右边的高度,防止接下来的左旋导致左侧树高度增长过大
x.right = rotateRight(x.right);
}
x = rotateLeft(x); // 左旋
} else if (tmp > 1) {
if (balanceCheck(x.left) < 0) {
x.left = rotateLeft(x.left);
}
x = rotateRight(x);
}
return x;
}
private int balanceCheck(Node x) {
return height(x.left) - height(x.right);
}
private int size(Node x) {
if (x == null) return 0;
return x.size;
}
private int height(Node x) {
if (x == null) return -1;
return x.height;
}
private Node rotateLeft(Node x) {
Node y = x.right;
x.right = y.left;
y.left = x;
y.size = x.size;
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
y.height = 1 + Math.max(height(y.left), height(y.right));
return y;
}
private Node rotateRight(Node x) {
Node y = x.left;
x.left = y.right;
y.right = x;
y.size = x.size;
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
y.height = 1 + Math.max(height(y.left), height(y.right));
return y;
}
private Node min(Node x) {
if (x.left == null) return x;
return min(x.left);
}
private Node deleteMin(Node x) {
if (x.left == null) return x.right;
x.left = deleteMin(x.left);
x.size = 1 + size(x.left) + size(x.right);
x.height = 1 + Math.max(height(x.left), height(x.right));
return balance(x);
}
public static void main(String[] args) {
AVLTree<Integer, Long> tree = new AVLTree<>();
long l = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
tree.insert(i, i * 2L);
}
System.out.println(tree.delete(6));
System.out.println(System.currentTimeMillis() - l + "MS");
}
}