Created
March 7, 2012 08:01
-
-
Save brenttaylor/1991804 to your computer and use it in GitHub Desktop.
Chad's AVL Tree in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mycollections; | |
public class AVLTree<T extends Comparable<T>> extends BinarySearchTree<T> { | |
public AVLTree() {super();} | |
public void add(T data) { | |
System.out.println("Insertion of :" + data.toString()); | |
AVLTreeNode parent = (AVLTreeNode) root; | |
Stack<Boolean> leftMoves; | |
Stack<AVLTreeNode> parents; | |
boolean placeNotFound = true; | |
if(root == null) { | |
root = new AVLTreeNode<T>(data); | |
System.out.println("\n\n"); | |
return; | |
} | |
parents = new LinkedStack<AVLTreeNode>(); | |
leftMoves = new LinkedStack<Boolean>(); | |
// Look for a place to put the node | |
while(placeNotFound) { | |
int cmp = parent.data.compareTo(data); | |
if(cmp == 0) return; // node is already there | |
if(cmp > 0) { // parent.data > data | |
if(parent.left == null) { | |
placeNotFound = false; | |
parent.left = new AVLTreeNode<T>(data); | |
} else { | |
parents.push(parent); | |
leftMoves.push(true); | |
parent = (AVLTreeNode) parent.left; | |
} | |
} else { | |
if(parent.right == null) { | |
placeNotFound = false; | |
parent.right = new AVLTreeNode<T>(data); | |
} else { | |
parents.push(parent); | |
leftMoves.push(false); | |
parent = (AVLTreeNode) parent.right; | |
} | |
} | |
} | |
boolean calculatingBF = true; | |
while(calculatingBF) { | |
System.out.println("CalculatingBF On:" + parent.data.toString()); | |
int bf = 0, lbf = 0, rbf = 0; | |
parent.balanceFactor = bf = calcBF(parent); | |
System.out.println(bf); | |
AVLTreeNode newParent = null; | |
// Rotates if needed | |
if(bf <= -2) { | |
if(rightBF((AVLTreeNode)parent.left) == 1) { | |
System.out.println("Rotate Left Child Left"); | |
parent.left = rotateLeft((AVLTreeNode)parent.left); | |
} | |
newParent = rotateRight(parent); | |
System.out.println("Rotate Parent Right"); | |
} else if (bf >= 2) { | |
if(leftBF((AVLTreeNode)parent.right) == -1) { | |
System.out.println("Rotate Right Child Right"); | |
parent.right = rotateRight((AVLTreeNode)parent.right); | |
} | |
System.out.println("Rotate Parent Left"); | |
newParent = rotateLeft(parent); | |
} | |
// All rotates need to deal with this | |
parent.balanceFactor = calcBF(parent); | |
if(bf <= -2 || bf >= 2) { | |
parent = parents.pop(); | |
if(parent == null) { | |
root = newParent; | |
} else if(parent.balanceFactor == 1) { | |
parent.right = newParent; | |
} else { | |
parent.left = newParent; | |
} | |
calculatingBF = false; | |
} else { | |
parent = parents.pop(); | |
if(parent == null) calculatingBF = false; | |
} | |
} | |
System.out.println("\n\n"); | |
} | |
protected int leftBF(AVLTreeNode parent) { | |
int lbf = 0; | |
if(parent.left == null) { | |
lbf = 0; | |
} else { | |
if(((AVLTreeNode)parent.left).balanceFactor == 0) { | |
lbf = -1; | |
} else { | |
lbf = -2; | |
} | |
} | |
return lbf; | |
} | |
protected int rightBF(AVLTreeNode parent) { | |
int rbf = 0; | |
if(parent.right == null) { | |
rbf = 0; | |
} else { | |
if(((AVLTreeNode)parent.right).balanceFactor == 0) { | |
rbf = 1; | |
} else { | |
rbf = 2; | |
} | |
} | |
return rbf; | |
} | |
protected int calcBF(AVLTreeNode parent) { | |
int lbf = leftBF(parent); | |
int rbf = rightBF(parent); | |
return lbf + rbf; | |
} | |
protected AVLTreeNode<T> rotateRight(AVLTreeNode parent) { | |
AVLTreeNode<T> newParent = (AVLTreeNode)parent.left; | |
parent.left = newParent.right; | |
newParent.right = parent; | |
parent.balanceFactor = calcBF(parent); | |
newParent.balanceFactor = calcBF(newParent); | |
return newParent; | |
} | |
protected AVLTreeNode<T> rotateLeft(AVLTreeNode parent) { | |
AVLTreeNode<T> newParent = (AVLTreeNode)parent.right; | |
parent.right = newParent.left; | |
newParent.left = parent; | |
parent.balanceFactor = calcBF(parent); | |
newParent.balanceFactor = calcBF(newParent); | |
return newParent; | |
} | |
public void CustomCheck() { | |
System.out.println(root.data); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mycollections; | |
public class AVLTreeNode<T extends Comparable<T>> extends BinaryTreeNode<T> { | |
protected int balanceFactor; | |
public AVLTreeNode() { this(null, null, null);} | |
public AVLTreeNode(T data) { this(data, null, null);} | |
public AVLTreeNode(T data, AVLTreeNode<T> l, AVLTreeNode<T> r) { | |
super(data, l, r); | |
balanceFactor = 0; | |
} | |
public int getBalanceFactor() {return balanceFactor;} | |
public void setBalanceFactor(int bf) {this.balanceFactor = bf;} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mycollections; | |
/** | |
* This is just a place where I might test some code, but in general I will try | |
* to use JUnit to test code rather than this class. | |
* @author Chad Lucas | |
*/ | |
public class MyCollections { | |
public static void main(String[] args) { | |
AVLTree<String> words = new AVLTree<String>(); | |
words.add("Z"); | |
words.add("Y"); | |
words.add("X"); | |
words.add("A"); | |
words.add("B"); | |
words.add("C"); | |
words.printPreOrder(); | |
System.out.println(words.MaxDepth()); | |
System.out.println(words.MinDepth()); | |
//words.CustomCheck(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment