assn06
This commit is contained in:
203
src/assn06/AVLTree.java
Normal file
203
src/assn06/AVLTree.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package assn06;
|
||||
|
||||
public class AVLTree<T extends Comparable<T>> implements SelfBalancingBST<T> {
|
||||
// Fields
|
||||
private T _value;
|
||||
private AVLTree<T> _left;
|
||||
private AVLTree<T> _right;
|
||||
private int _height;
|
||||
private int _size;
|
||||
|
||||
public AVLTree() {
|
||||
_value = null;
|
||||
_left = null;
|
||||
_right = null;
|
||||
_height = -1;
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
private void updateMeta() {
|
||||
this._height = 1 + Math.max(this._left.height(), this._right.height());
|
||||
this._size = 1 + this._left.size() + this._right.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the tree left and returns
|
||||
* AVLTree root for rotated result.
|
||||
*/
|
||||
private AVLTree<T> rotateLeft() {
|
||||
if (isEmpty())
|
||||
throw new RuntimeException("Illegal operation on empty tree");
|
||||
|
||||
AVLTree<T> newRoot = this._right;
|
||||
this._right = newRoot._left;
|
||||
newRoot._left = this;
|
||||
|
||||
newRoot._left.updateMeta();
|
||||
newRoot.updateMeta();
|
||||
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the tree right and returns
|
||||
* AVLTree root for rotated result.
|
||||
*/
|
||||
private AVLTree<T> rotateRight() {
|
||||
if (isEmpty())
|
||||
throw new RuntimeException("Illegal operation on empty tree");
|
||||
|
||||
AVLTree<T> newRoot = this._left;
|
||||
this._left = newRoot._right;
|
||||
newRoot._right = this;
|
||||
|
||||
newRoot._right.updateMeta();
|
||||
newRoot.updateMeta();
|
||||
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int height() {
|
||||
return _height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
private int balanceFactor() {
|
||||
return _left.height() - _right.height();
|
||||
}
|
||||
|
||||
private SelfBalancingBST<T> rebalance() {
|
||||
AVLTree<T> self = this;
|
||||
self.updateMeta();
|
||||
|
||||
if (self.balanceFactor() > 1)
|
||||
if (self._left.balanceFactor() < 0) {
|
||||
self._left = self._left.rotateLeft();
|
||||
self = self.rotateRight();
|
||||
} else
|
||||
self = self.rotateRight();
|
||||
else if (self.balanceFactor() < -1)
|
||||
if (self._right.balanceFactor() > 0) {
|
||||
self._right = self._right.rotateRight();
|
||||
self = self.rotateLeft();
|
||||
} else
|
||||
self = self.rotateLeft();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfBalancingBST<T> insert(T element) {
|
||||
if (isEmpty()) {
|
||||
_value = element;
|
||||
_left = new AVLTree<T>();
|
||||
_right = new AVLTree<T>();
|
||||
_height = 0;
|
||||
_size = 1;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (_value.compareTo(element) > 0)
|
||||
_left = (AVLTree<T>) _left.insert(element);
|
||||
else if (_value.compareTo(element) < 0)
|
||||
_right = (AVLTree<T>) _right.insert(element);
|
||||
|
||||
return this.rebalance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfBalancingBST<T> remove(T element) {
|
||||
if (!contains(element))
|
||||
return this;
|
||||
|
||||
if (_value.compareTo(element) > 0)
|
||||
_left = (AVLTree<T>) _left.remove(element);
|
||||
else if (_value.compareTo(element) < 0)
|
||||
_right = (AVLTree<T>) _right.remove(element);
|
||||
else {
|
||||
if (_left.isEmpty() && _right.isEmpty())
|
||||
return new AVLTree<T>();
|
||||
else if (_left.isEmpty())
|
||||
return _right;
|
||||
else if (_right.isEmpty())
|
||||
return _left;
|
||||
else {
|
||||
_value = _right.findMin();
|
||||
_right = (AVLTree<T>) _right.remove(_value);
|
||||
}
|
||||
}
|
||||
|
||||
return this.rebalance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T findMin() {
|
||||
if (isEmpty()) {
|
||||
throw new RuntimeException("Illegal operation on empty tree");
|
||||
}
|
||||
if (_left.isEmpty()) {
|
||||
return _value;
|
||||
} else {
|
||||
return _left.findMin();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T findMax() {
|
||||
if (isEmpty()) {
|
||||
throw new RuntimeException("Illegal operation on empty tree");
|
||||
}
|
||||
if (_right.isEmpty()) {
|
||||
return _value;
|
||||
} else {
|
||||
return _right.findMax();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(T element) {
|
||||
if (isEmpty())
|
||||
return false;
|
||||
|
||||
if (_value.compareTo(element) == 0)
|
||||
return true;
|
||||
else if (_value.compareTo(element) > 0)
|
||||
return _left.contains(element);
|
||||
else
|
||||
return _right.contains(element);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getValue() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfBalancingBST<T> getLeft() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return _left;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfBalancingBST<T> getRight() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return _right;
|
||||
}
|
||||
|
||||
}
|
||||
42
src/assn06/Main.java
Normal file
42
src/assn06/Main.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package assn06;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Create a new empty tree.
|
||||
SelfBalancingBST<Integer> avl_bst = new AVLTree<Integer>();
|
||||
|
||||
// Insert 50 random integers.
|
||||
// Note how we need to capture the result of insert back into
|
||||
// the variable avl_bst because the post-insertion root that is
|
||||
// returned may be different from the original root because of the insertion.
|
||||
// result should be about 6.
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
int rand = (int) (Math.random() * 100);
|
||||
while (avl_bst.contains(rand))
|
||||
rand = (int) (Math.random() * 100);
|
||||
|
||||
avl_bst = avl_bst.insert(rand);
|
||||
}
|
||||
System.out.println("\nheight: " + avl_bst.height());
|
||||
System.out.println("size: " + avl_bst.size());
|
||||
|
||||
// Now insert 50 integers in increasing order which would
|
||||
// cause a simple BST to become very tall but for our
|
||||
// self-balancing tree won't be too bad (should be 7)
|
||||
|
||||
for (int i = 150; i < 200; i++) {
|
||||
avl_bst = avl_bst.insert(i);
|
||||
}
|
||||
System.out.println("\nheight: " + avl_bst.height());
|
||||
System.out.println("size: " + avl_bst.size());
|
||||
|
||||
// test remove
|
||||
avl_bst = avl_bst.remove(avl_bst.findMax());
|
||||
avl_bst = avl_bst.remove(avl_bst.findMin());
|
||||
|
||||
System.out.println("\nheight: " + avl_bst.height());
|
||||
System.out.println("size: " + avl_bst.size());
|
||||
}
|
||||
}
|
||||
76
src/assn06/SelfBalancingBST.java
Normal file
76
src/assn06/SelfBalancingBST.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package assn06;
|
||||
|
||||
public interface SelfBalancingBST<T extends Comparable<T>> {
|
||||
|
||||
/**
|
||||
* @return true if the tree is empty
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* @return height of the tree.
|
||||
*/
|
||||
int height();
|
||||
|
||||
/**
|
||||
* @return the number of elements in the tree
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Inserts element into tree and returns resulting
|
||||
* tree (i.e. root) after insertion. Depending on implementation,
|
||||
* this may or may not be the same object that you started with.
|
||||
* @param element to be added to the tree
|
||||
* @return resulting tree after insertion
|
||||
**/
|
||||
SelfBalancingBST<T> insert(T element);
|
||||
|
||||
/**
|
||||
* Removes element from tree and returns resulting
|
||||
* tree after removal. Depending on implementation,
|
||||
* this may or may not be the same object that you
|
||||
* started with. If element is not in the tree, the
|
||||
* tree should remain unchanged and return itself.
|
||||
* @param element to be removed from the tree
|
||||
* @return resulting tree after removal
|
||||
**/
|
||||
SelfBalancingBST<T> remove(T element);
|
||||
|
||||
/**
|
||||
* Throws a RuntimeException if called on an empty tree.
|
||||
* @return the smallest value in the tree
|
||||
*/
|
||||
T findMin();
|
||||
|
||||
/**
|
||||
* Throws a RuntimeException if called on an empty tree.
|
||||
* @return the smallest value in the tree.
|
||||
*/
|
||||
T findMax();
|
||||
|
||||
/**
|
||||
* @param element whose presence in this tree is to be tested
|
||||
* @return true if this tree contains the specified element
|
||||
*/
|
||||
boolean contains(T element);
|
||||
|
||||
/**
|
||||
* @return value at the top of the tree.
|
||||
* If a tree is empty, its value is null.
|
||||
*/
|
||||
T getValue();
|
||||
|
||||
/**
|
||||
* @return the left child of the tree.
|
||||
* Throws a RuntimeException if the tree is empty.
|
||||
*/
|
||||
SelfBalancingBST<T> getLeft();
|
||||
|
||||
/**
|
||||
* @return the right child of the tree.
|
||||
* Throws a RuntimeException if the tree is empty.
|
||||
*/
|
||||
SelfBalancingBST<T> getRight();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user