/*
Copyright 2010 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.util;
/*
* HeapSort.java
*
* Created: Fri Jan 25 2002
* By: Liviu Panait
*/
/**
* Implementations of Heap functions in Java. This code is derived
* from the HeapSort example algorithm in <i>Introduction to algorithms</i> by
* Cormen, Leiserson and Rivest. Intentionally very simple.
*
* <p>This code uses doubles as keys; as opposed to sim.util.Heap, which uses
* Comparables as keys.
*
* @author Liviu Panait
* @version 1.0
*/
public class DoubleHeap implements java.io.Serializable
{
// the keys
double[] keys = null;
// the information associated with the keys
Object[] objects = null;
int numElem = 0;
// constructs the heap
public DoubleHeap()
{
this(new double[0], new Object[0], 0);
}
// constructs the heap
public DoubleHeap( double[] keys, Object[] objects, int numElem )
{
if (keys.length != objects.length)
throw new IllegalArgumentException("keys and objects must be of the same length");
this.keys = keys;
this.objects = objects;
this.numElem = numElem;
buildHeap();
}
// builds the heap
void buildHeap()
{
for( int i = numElem/2 ; i >= 1 ; i-- )
heapify( i, numElem );
}
void heapify( int i, int heapsize )
{
// make local
Object[] objects = this.objects;
double[] keys = this.keys;
while( true )
{
int l = 2*i;
int r = 2*i+1;
int smallest;
if( l <= heapsize && keys[l-1] < keys[i-1] )
smallest = l;
else
smallest = i;
if( r <= heapsize && keys[r-1] < keys[smallest-1] )
smallest = r;
if( smallest != i )
{
// swap keys
double tempkey = keys[i-1];
keys[i-1] = keys[smallest-1];
keys[smallest-1] = tempkey;
// swap info
Object temp = objects[i-1];
objects[i-1] = objects[smallest-1];
objects[smallest-1] = temp;
// recursive call.... :)
i = smallest;
}
else
return;
}
}
/** Returns the key value of the current min element. Does not extract the element. */
public double getMinKey()
{
return keys[1-1];
}
/** Removes the minimum element and its key from the heap, and returns the minimum element. Will return null if the heap is empty */
public Object extractMin()
{
// make local
int numElem = this.numElem;
Object[] objects = this.objects;
double[] keys = this.keys;
if( numElem == 0 )
return null;
// remove the key
keys[1-1] = keys[numElem-1];
keys[numElem-1] = 0;
// remove the info
Object result = objects[1-1];
objects[1-1] = objects[numElem-1];
objects[numElem-1]=null;
numElem--;
// rebuild heap
heapify( 1, numElem );
// return the info with min key (which was also removed from the heap)
// put back
this.numElem = numElem;
return result;
}
/** Adds an element to the heap with the given key. */
public void add( Object elem, double key )
{
// make local
int numElem = this.numElem;
Object[] objects = this.objects;
double[] keys = this.keys;
numElem++;
if( (numElem-1) >= objects.length )
{
Object[] temp = new Object[ objects.length * 2 + 1];
System.arraycopy( objects, 0, temp, 0, objects.length );
objects = temp;
double[] temptemp = new double[ keys.length * 2 + 1];
System.arraycopy( keys, 0, temptemp, 0, keys.length );
keys = temptemp;
// objects and keys may have changed
this.objects = objects;
this.keys = keys;
}
int i = numElem;
while ( i > 1 && keys[i/2-1] > key )
{
objects[i-1] = objects[i/2-1];
keys[i-1] = keys[i/2-1];
i = i/2;
}
keys[i-1] = key;
objects[i-1] = elem;
// put back
this.numElem = numElem;
}
public boolean isEmpty()
{
return (numElem==0);
}
public void clear()
{
numElem = 0;
}
}