package com.github.dql.avltree;
public class AvlTree<T extends Comparable<T>> {
private Node root;
public AvlTree() {
root = null;
}
public void create(T[] keys) {
for (T key : keys) {
Insert(key);
}
}
public void Insert(T key) {
root = insert(root, key);
}
public void preOrderTraverse() {
preOrderTraverse(root);
}
public void inOrderTraverse() {
inOrderTraverse(root);
}
public void postOrderTraverse() {
postOrderTraverse(root);
}
private void preOrderTraverse(Node root) {
if (root != null) {
System.out.println(root.key);
preOrderTraverse(root.leftChild);
preOrderTraverse(root.rightChild);
}
}
private void inOrderTraverse(Node root) {
if (root != null) {
inOrderTraverse(root.leftChild);
System.out.println(root.key);
inOrderTraverse(root.rightChild);
}
}
private void postOrderTraverse(Node root) {
if (root != null) {
postOrderTraverse(root.leftChild);
postOrderTraverse(root.rightChild);
System.out.println(root.key);
}
}
private Node insert(Node root, T key) {
if (root == null) {
root = new Node(key, 0, null, null);
} else if (root.key.compareTo(key) < 0) {
root.rightChild = insert(root.rightChild, key);
if (getHeight(root.rightChild) - getHeight(root.leftChild) == 2) {
if (root.rightChild.key.compareTo(key) < 0)
root = singleRotateWithRight(root);
else
root = doubleRotateWithRight(root);
}
} else if (root.key.compareTo(key) > 0) {
root.leftChild = insert(root.leftChild, key);
if (getHeight(root.leftChild) - getHeight(root.rightChild) == 2) {
if (root.leftChild.key.compareTo(key) > 0)
root = singleRotateWithLeft(root);
else
root = doubleRotateWithLeft(root);
}
} else {}
updateHeight(root);
return root;
}
private int getHeight(Node root) {
if (root == null)
return -1;
return root.height;
}
private void updateHeight(Node root) {
root.height = Math.max(
getHeight(root.leftChild), getHeight(root.rightChild)) + 1;
}
private Node singleRotateWithLeft(Node unbalanced) {
Node left = unbalanced.leftChild;
unbalanced.leftChild = left.rightChild;
left.rightChild = unbalanced;
updateHeight(left);
updateHeight(unbalanced);
return left;
}
private Node singleRotateWithRight(Node unbalanced) {
Node right = unbalanced.rightChild;
unbalanced.rightChild = right.leftChild;
right.leftChild = unbalanced;
updateHeight(right);
updateHeight(unbalanced);
return right;
}
private Node doubleRotateWithLeft(Node unbalanced) {
unbalanced.leftChild = singleRotateWithRight(unbalanced.leftChild);
return singleRotateWithLeft(unbalanced);
}
private Node doubleRotateWithRight(Node unbalanced) {
unbalanced.rightChild = singleRotateWithLeft(unbalanced.rightChild);
return singleRotateWithRight(unbalanced);
}
private class Node {
public T key;
public int height;
public Node leftChild;
public Node rightChild;
public Node(T key, int height, Node leftChild, Node rightChild) {
this.key = key;
this.height = height;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
}
public static void main(String[] args) {
AvlTree<Integer> avl = new AvlTree<>();
avl.create(new Integer[]{7, 3, 11, 9, 16, 26});
avl.preOrderTraverse();
}
}