I'm building a treap class in Java. Below is my function for adding new nodes to the treap. The process is: traverse down to bottom of treap (while adding each node in the path to a local stack) only worrying about the BST structure at first, then, once at the bottom, I'm reestablishing the heap invariant through rotations by utilizing the stack I built.
It sounds like it should work, but I keep getting an EmptyStackException. This exception occurs once the private "reheap" function is called.
The add function works for the first node added to the treap, such as if I did: testTree.add (4 ,19); But fails upon the second addition of a node, like if I then call: testTree.add (2 ,31);
This is the full error:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at classes.Treap.reheap(Treap.java:137)
at classes.Treap.add(Treap.java:130)
at classes.Treap.main(Treap.java:220)
130 -- refers to the call to reheap at the bottom of the add function 137 -- refers to the while loop of the private reheap function 220 -- refers to my attempt to add the new node in main.
I've tried changing around the conditionals in the reheap function, but to no avail.
boolean add(E key, int priority) {
Stack<Node<E>> stack = new Stack<Node<E>>();
if(root == null) {
Node<E> newroot = new Node<E>(key, priority);
root = newroot;
stack.push(root);
return true;
}else {
Node<E> current = new Node<E>(root.data, root.priority); //placeholder, used for traversing
Node<E> added = new Node<E>(key, priority); //node to be added to the treap
if(this.find(key) == true){
return false;
}else {
if(current.right == null && current.left == null) {
stack.push(current);
if(key.compareTo(current.data) < 0)
current = current.left;
else
current = current.right;
}
else {
while(current.right != null || current.left != null) {
if(key.compareTo(current.data) < 0) {
stack.push(current);
current = current.left;
}
if(key.compareTo(current.data) > 0) {
stack.push(current);
current = current.right;
}
}
}
if(key.compareTo(stack.peek().data) < 0)
stack.peek().left = added;
else if(key.compareTo(stack.peek().data) > 0)
stack.peek().right = added;
if(!stack.isEmpty())
this.reheap(added, stack);
return true;
}
}
}
private boolean reheap(Node<E> added, Stack<Node<E>> stack) {
while(added.priority > stack.peek().priority && !stack.isEmpty()) {
if(stack.peek().right == added)
stack.peek().rotateLeft();
else
stack.peek().rotateRight();
stack.pop();
}
return true;
}
After the second call ( testTree.add (2 ,31)
; ), I should be getting a treap with structure ( Node(2, null, Node(4)) ). <-- this would be after the reheaping of course.
You need to do the empty stack check prior to peeking the stack!
while(!stack.isEmpty() && added.priority > stack.peek().priority) {...}