You are on page 1of 7

# import java.util.

ArrayList;
/**
* This class is the complete and tested implementation of an AVL-tree.
*/
public class AvlTree {
protected AvlNode root; // the root node
/***************************** Core Functions **********************************
**/
/**
* Add a new element with key "k" into the tree.
*
* @param k
*
The key of the new node.
*/
public void insert(int k) {
// create new node
AvlNode n = new AvlNode(k);
// start recursive procedure for inserting the node
insertAVL(this.root,n);
}
/**
* Recursive method to insert a node into a tree.
*
* @param p The node currently compared, usually you start with the root.
* @param q The node to be inserted.
*/
public void insertAVL(AvlNode p, AvlNode q) {
// If node to compare is null, the node is inserted. If the root is null, it
is the root of the tree.
if(p==null) {
this.root=q;
} else {
// If compare node is smaller, continue with the left node
if(q.key<p.key) {
if(p.left==null) {
p.left = q;
q.parent = p;
// Node is inserted now, continue checking the balance
recursiveBalance(p);
} else {
insertAVL(p.left,q);
}
} else if(q.key>p.key) {
if(p.right==null) {
p.right = q;
q.parent = p;
// Node is inserted now, continue checking the balance
recursiveBalance(p);
} else {
insertAVL(p.right,q);
}

int q) { if(p==null) { .root = cur. } else { cur = doubleRotateLeftRight(cur). */ public void remove(int k) { // First we must find the node.right)>=height(cur.right.left. } } // we did not reach the root yet if(cur. * * @param cur : The node to check the balance for. after this we can delete it.root.right.left)) { cur = rotateLeft(cur).balance. */ public void recursiveBalance(AvlNode cur) { // we do not use the balance in this class. } else { this. } } else if(balance==2) { if(height(cur.right)) { cur = rotateRight(cur). // check the balance if(balance==-2) { if(height(cur. if it is existent. System.out.println("-----------.left. removeAVL(this.k).} else { // do nothing: This node already exists } } } /** * Check the balance for each node recursivly and call required methods for bal ancing the tree until the root is reached. but the store it anyway setBalance(cur). } else { cur = doubleRotateRightLeft(cur). int balance = cur.left)>=height(cur. * @param q The KEY of node to remove. } } /** * Removes a node from the tree. usually you start with the p arent of a leaf. * * @param p The node to start the search.parent!=null) { recursiveBalance(cur. } /** * Finds a node and calls a method to remove the node.Balancing finished ----------------"). */ public void removeAVL(AvlNode p.parent).

q.left.key = r.right==null) { // the root is deleted if(q.left=p. while balancing will be done if necessary. } r = q.// der Wert existiert nicht in diesem Baum.key>q) { removeAVL(p. recursiveBalance(r. } . now lets go on! removeFoundNode(p). } else { if(r==r.q). // at least one child of q.key.root = p.right. } else { p = r.key<q) { removeAVL(p. } else { if(p. } else { // q has two children --> will be replaced by successor r = successor(q).root=null. q=null.right.parent.parent. return. } if(r. } if(p!=null) { p.q). } // balancing must be done until the root is reached.left) { r..left==null || q. q will be removed directly if(q.parent. } r = null.key==q) { // we found the node in the tree. } } } /** * Removes a node from a AVL-Tree. } else if(p. */ public void removeFoundNode(AvlNode q) { AvlNode r.parent = r. } else { r. daher ist nichts zu tun return. } else if(p. * * @param q The node to be removed.parent==null) { this. if(r.left.parent).right = p.parent==null) { this.left!=null) { p = r.parent. } AvlNode p.

parent = v.parent = n.left.right.parent = v.left = n. if(n.left!=null) { n.parent.right. if(v.parent. } } setBalance(n). n. n.right!=null) { n.left = v.left = v. * * @return The root of the rotated tree. } else if(v.right.parent.left==n) { v. n. . return v./** * Left rotation using the given node. } v.parent=n. * * @param n * The node for the rotation * * @return The root of the new rotated tree.parent!=null) { if(v.parent.parent = n.left.right==n) { v.right = v. } /** * Right rotation using the given node. v.left. } v. if(n.right = n.parent=n. */ public AvlNode rotateRight(AvlNode n) { AvlNode v = n.parent.parent. n. */ public AvlNode rotateLeft(AvlNode n) { AvlNode v = n. setBalance(v). * * * @param n * The node for the rotation.right = v. v.

left = v.parent. } return p. */ public AvlNode doubleRotateLeftRight(AvlNode u) { u.if(v. } /***************************** Helper Functions ******************************** ****/ /** * Returns the successor of a given node in the tree (search recursivly).right. } else { AvlNode p = q.parent.left==n) { v. setBalance(v). * @return The successor of node q.left!=null) { r = r.parent. } } setBalance(n). return rotateRight(u). * @return The root after the double rotation.parent.left).right) { q = p. return v. } /** * * @param u The node for the rotation.right!=null) { AvlNode r = q.right). } return r.left = rotateLeft(u. */ public AvlNode doubleRotateRightLeft(AvlNode u) { u. } else if(v. } } . * * @param q The predecessor.parent. } /** * * @param u The node for the rotation.right==n) { v.parent!=null) { if(v. */ public AvlNode successor(AvlNode q) { if(q. while(r.right = rotateRight(u. while(p!=null && q==p. p = q. * @return The root after the double rotation.parent.left. return rotateLeft(u).right = v.

key. * * @param cur * @return The height of a node (-1. if(n. } System. */ private int maximum(int a.left!=null) { l = n.out. int r = 0.height(cur. } if(n.right!=null) { debug(n. int b) { if(a>=b) { return a.parent!=null) { p = n.right)). if(n./** * Calculating the "height" of a node.balance). * @param n The node to write information about. Gives all information about a node. NULL).right). */ private int height(AvlNode cur) { if(cur==null) { return -1.right==null) { return 0.left==null) { return 1+height(cur.left==null && cur.right).left. } if(n. } else { return 1+maximum(height(cur. } } /** * Return the maximum of two integers.key. int p = 0.left).parent. } .left).left!=null) { debug(n. } else { return b.right!=null) { r = n.right==null) { return 1+height(cur. */ public void debug(AvlNode n) { int l = 0.key.left).right. } else if(cur.println("Left: "+l+" Key: "+n+" Right: "+r+" Parent: "+p+" Balance: "+n. if node is not existent eg. } else if(cur. } if(n. } if(cur. } } /** * Only for debugging purposes.

* * @return A Array-List of the tree in inorder traversal. ret).right)-height(cur. key = k. * * @param n * The current node. } inorder(n. */ final protected ArrayList<AvlNode> inorder() { ArrayList<AvlNode> ret = new ArrayList<AvlNode>(). public AvlNode right. } /** * Function to calculate inorder recursivly. inorder(root. */ final protected void inorder(AvlNode n. io). balance = 0. * @param io * The list to save the inorder traversal.balance = height(cur. io).right. } } . public AvlNode(int k) { left = right = parent = null. } } /** Here is the AVL-Node class for Completenesse **/ public class AvlNode { public AvlNode left. inorder(n. } /** * Calculates the Inorder traversal of this tree. ArrayList<AvlNode> io) { if (n == null) { return.left.} private void setBalance(AvlNode cur) { cur. } public String toString() { return "" + key.add(n). io. public int balance. public AvlNode parent. public int key. return ret.left).