public class AVLTree extends BinarySearchTree {
public void insert(int key, String data) {
int iteratorKey = 0;
TreeNode tmpRoot = null;
TreeNode iterator = null;
TreeNode treeNode = new TreeNode(key, data);
if (root == null) {
root = treeNode;
numNodes++;
} else {
iterator = root;
while (true) {
tmpRoot = iterator;
iteratorKey = iterator.getKey();
if (iteratorKey == key) {
iterator.setData(data);
break;
} else if (key < iteratorKey) {
iterator = iterator.getLeft();
if (iterator == null) {
tmpRoot.setLeft(treeNode);
numNodes++;
break;
}
} else if (key > iteratorKey) {
iterator = iterator.getRight();
if (iterator == null) {
tmpRoot.setRight(treeNode);
numNodes++;
break;
}
}
}
treeNode.setParent(tmpRoot);
doRebalance(treeNode);
}
}
private void doRebalance(TreeNode theNode) {
int heightCounter = 0;
TreeNode iterator = theNode;
TreeNode child = theNode;
while (iterator != root) {
child = iterator;
iterator = iterator.getParent();
heightCounter++;
if (iterator.getHeight() <= heightCounter) {
iterator.setHeight(heightCounter);
}
if (!isBalanced(iterator)) {
doRotation(iterator, child, theNode);
return;
}
}
}
private void doRotation(TreeNode m, TreeNode n, TreeNode theNode) {
TreeNode o = null;
if (n.getKey() < theNode.getKey()) {
o = n.getRight();
} else {
o = n.getLeft();
}
if ((m.getKey() < n.getKey()) && (n.getKey() < o.getKey())) {
doSingleLeftRotation(m, n);
} else if ((m.getKey() < n.getKey()) && (n.getKey() > o.getKey())) {
doDoubleLeftRotation(m, n, o);
} else if ((m.getKey() > n.getKey()) && (n.getKey() > o.getKey())) {
doSingleRightRotation(m, n);
} else if ((m.getKey() > n.getKey()) && (n.getKey() < o.getKey())) {
doDoubleRightRotation(m, n, o);
}
}
private void doDoubleLeftRotation(TreeNode m, TreeNode n, TreeNode o) {
m.setRight(o.getLeft());
if (o.getLeft() != null) {
o.getLeft().setParent(m);
}
n.setLeft(o.getRight());
if (o.getRight() != null) {
o.getRight().setParent(n);
}
o.setLeft(m);
o.setRight(n);
if (m == root) {
root = o;
o.setParent(null);
} else {
if (m.getParent().getKey() < m.getKey()) {
m.getParent().setRight(o);
} else {
m.getParent().setLeft(o);
}
o.setParent(m.getParent());
}
m.setParent(o);
n.setParent(o);
m.setHeight(m.getHeight() - 2);
n.setHeight(n.getHeight() - 1);
o.setHeight(o.getHeight() + 2);
}
private void doDoubleRightRotation(TreeNode m, TreeNode n, TreeNode o) {
m.setLeft(o.getRight());
if (o.getRight() != null) {
o.getRight().setParent(m);
}
n.setRight(o.getLeft());
if (o.getLeft() != null) {
o.getLeft().setParent(n);
}
o.setLeft(n);
o.setRight(m);
if (m == root) {
root = o;
o.setParent(null);
} else {
if (m.getParent().getKey() > m.getKey()) {
m.getParent().setLeft(o);
} else {
m.getParent().setRight(o);
}
o.setParent(m.getParent());
}
m.setParent(o);
n.setParent(o);
m.setHeight(m.getHeight() - 2);
n.setHeight(n.getHeight() - 1);
o.setHeight(o.getHeight() + 2);
}
private void doSingleLeftRotation(TreeNode m, TreeNode n) {
m.setRight(n.getLeft());
if (n.getLeft() != null) {
n.getLeft().setParent(m);
}
n.setLeft(m);
if (m == root) {
root = n;
n.setParent(null);
} else {
if (m.getParent().getKey() < m.getKey()) {
m.getParent().setRight(n);
} else {
m.getParent().setLeft(n);
}
n.setParent(m.getParent());
}
m.setParent(n);
m.setHeight(m.getHeight() - 2);
n.setHeight(n.getHeight() + 1);
}
private void doSingleRightRotation(TreeNode m, TreeNode n) {
m.setLeft(n.getRight());
if (n.getRight() != null) {
n.getRight().setParent(m);
}
n.setRight(m);
if (m == root) {
root = n;
n.setParent(null);
} else {
if (m.getParent().getKey() < m.getKey()) {
m.getParent().setRight(n);
} else {
m.getParent().setLeft(n);
}
n.setParent(m.getParent());
}
m.setParent(n);
m.setHeight(m.getHeight() - 2);
n.setHeight(n.getHeight() + 1);
}
private int getNodeHeight(TreeNode node) {
if (node == null) {
return -1;
} else {
return node.getHeight();
}
}
private boolean isBalanced(TreeNode node) {
int balance = (1 + getNodeHeight(node.getRight())) - (1 + getNodeHeight(node.getLeft()));
switch (balance) {
case - 1:
case 0:
case 1:
return true;
}
return false;
}
public boolean delete(int searchKey) {
System.out.println("You are not required to implement deletion for an AVL tree");
return false;
}
}