package algorithmbasic.basicsets.class36;
import java.util.Map;
public class AVL {
public static class AvlNode<K extends Comparable<K>, V> {
public K key;
public V value;
public AvlNode l;
public AvlNode r;
public Integer h;
public AvlNode(K key, V value) {
this.key = key;
this.value = value;
this.h = 0;
}
}
public static class AvlTreeMap<K extends Comparable<K>, V> {
AvlNode<K, V> root;
public AvlNode<K, V> add(AvlNode<K, V> cur, K key, V value) {
if (cur == null) {
return new AvlNode(key, value);
}
if (cur.key.compareTo(key) < 0) {
cur.l = add(cur.l, key, value);
} else {
cur.r = add(cur.r, key, value);
}
cur.h = Math.max((cur.l == null ? 0 : cur.l.h), (cur.r == null ? 0 : cur.r.h)) + 1;
return maintain(cur);
}
public AvlNode<K, V> delete(AvlNode<K, V> cur, K key) {
if (cur.key.compareTo(key) < 0) {
cur.r = delete(cur.r, key);
} else if (cur.key.compareTo(key) > 0) {
cur.l = delete(cur.l, key);
} else {
if (cur.l == null && cur.r == null) {
cur = null;
} else if (cur.l != null && cur.r == null) {
cur = cur.l;
} else if (cur.r != null && cur.l == null) {
cur = cur.r;
} else {
AvlNode<K, V> des = cur.l;
while (des.l != null) {
des = des.l;
}
cur.r = delete(cur.r, des.key);
des.l = cur.l;
des.r = cur.r;
cur = des;
}
}
cur.h = Math.max((cur.l == null ? 0 : cur.l.h), (cur.r == null ? 0 : cur.r.h)) + 1;
return maintain(cur);
}
public AvlNode<K, V> maintain(AvlNode<K, V> cur) {
if (cur == null) {
return null;
}
int leftHeight = cur.l != null ? cur.l.h : 0;
int rightHeight = cur.r != null ? cur.r.h : 0;
if (Math.abs(leftHeight - rightHeight) > 1) {
if (leftHeight > rightHeight) {
int leftleftHeight = cur.l != null && cur.l.l != null ? cur.l.l.h : 0;
int leftrightHeight = cur.l != null && cur.l.r != null ? cur.l.r.h : 0;
if (leftleftHeight >= leftrightHeight) {
cur = rightRotate(cur);
} else {
cur.l = leftRotate(cur.l);
cur = rightRotate(cur);
}
} else {
int rightleftHeight = cur.r != null && cur.r.l != null ? cur.r.l.h : 0;
int rightrightHeight = cur.r != null && cur.r.r != null ? cur.r.r.h : 0;
if (rightleftHeight >= rightrightHeight) {
cur = leftRotate(cur);
} else {
cur.r = rightRotate(cur.r);
cur = leftRotate(cur);
}
}
}
return cur;
}
public AvlNode<K, V> rightRotate(AvlNode<K, V> cur) {
AvlNode left = cur.l;
cur.l = left.r;
left.r = cur;
cur.h = Math.max((cur.l != null ? cur.l.h : 0), (cur.r != null ? cur.r.h : 0));
left.h = Math.max((left.l != null ? left.l.h : 0), (left.r != null ? left.r.h : 0));
return left;
}
public AvlNode<K, V> leftRotate(AvlNode<K, V> cur) {
AvlNode right = cur.r;
cur.r = right.l;
right.l = cur;
cur.h = Math.max((cur.l != null ? cur.l.h : 0), (cur.r != null ? cur.r.h : 0));
right.h = Math.max((right.l != null ? right.l.h : 0), (right.r != null ? right.r.h : 0));
return right;
}
}
}