Data Structures, Algorithms, & Applications in Java
Chapter 13, Exercise 25
We use a single node
with element field set to
minElement
as a substitute for the null
pointer.
This simplifies the code for meld.
As it turns out, the new code does not use minElement
in any meaningful way and so we can eliminate this from
our specification.
The new code is given below.
The new class includes a class data member
minNode whose element field equals
minElement.
This class data member must be initialized by the user prior to
the construction of the first height biased leftist tree.
A test program and output appear in the files
MaxHbltWithMinElement.*.
public class MaxHbltWithMinElement implements MaxPriorityQueue
{
// top-level nested class
static class HbltNode
{
// data members
Comparable element;
int s; // shortest value
HbltNode leftChild; // pointer to left subtree
HbltNode rightChild; // pointer to right subtree
// constructor
private HbltNode(Comparable theElement, int theS, HbltNode theChild)
{
element = theElement;
s = theS;
leftChild = theChild;
rightChild = theChild;
}
}
// data members of MaxHbltWithMinElement
HbltNode root; // pointer to tree root
int size; // number of elements in tree
public static HbltNode minNode; // node with minElement
// constructor
public MaxHbltWithMinElement()
{root = minNode;}
// methods
/** @return true iff the tree is empty */
public boolean isEmpty()
{return size == 0;}
/** @return number of elements in the tree */
public int size()
{return size;}
/** @return maximum element
* @return null if the tree is empty */
public Comparable getMax()
{
if (size == 0) return null;
else return root.element;
}
/** meld the max leftist trees this and x
* on exit, this is the result */
public void meld(MaxHbltWithMinElement x)
{root = meld(root, x.root);}
/** meld the leftist trees with roots x and y
* @return pointer to root of resulting tree */
private static HbltNode meld(HbltNode x, HbltNode y)
{
if (y == minNode)
return x; // y is empty
if (x == minNode)
return y; // x is empty
// neither is empty, swap x and y if necessary
if (x.element.compareTo(y.element) < 0)
{// swap x and y
HbltNode t = x;
x = y;
y = t;
}
// now x.element >= y.element
x.rightChild = meld(x.rightChild, y);
// see if subtrees to be swapped, need not check for empty subtree
// swap only if left subtree has smaller s value
if (x.leftChild.s < x.rightChild.s)
{// swap subtrees
HbltNode t = x.leftChild;
x.leftChild = x.rightChild;
x.rightChild = t;
}
// update s value
x.s = x.rightChild.s + 1;
return x;
}
/** put theElement into the heap */
public void put(Comparable theElement)
{
if (theElement.compareTo(minNode.element) < 0)
throw new IllegalArgumentException
("cannot insert element smaller than " + minNode.element);
HbltNode q = new HbltNode (theElement, 1, minNode);
// meld q and original tree
root = meld(root, q);
size++;
}
/** remove max element and return it */
public Comparable removeMax()
{
if (size == 0)
return null; // tree is empty
// tree not empty
Comparable x = root.element; // save max element
root = meld(root.leftChild, root.rightChild);
size--;
return x;
}
/** initialize leftist tree to elements in array theElements */
public void initialize(Comparable [] theElements, int theSize)
{
size = theSize;
ArrayQueue q = new ArrayQueue(size);
// initialize queue of trees
for (int i = 1; i <= size; i++)
{// create trees with one node each
if (theElements[i].compareTo(minNode.element) < 0)
throw new IllegalArgumentException
("cannot have elements smaller than " + minNode.element);
q.put(new HbltNode(theElements[i], 1, minNode));
}
// repeatedly meld from queue q
for (int i = 1; i <= size - 1; i++)
{ // remove and meld two trees from the queue
HbltNode b = (HbltNode) q.remove();
HbltNode c = (HbltNode) q.remove();
b = meld(b, c);
// put melded tree on queue
q.put(b);
}
if (size > 0)
root = (HbltNode) q.remove();
}
}