Viewing file: comp352/assignment3/Deg3Heap.java | Back to directory listing
Author: Loren Segal | Last modified: February 21 2006 12:00 am | Download

/**
 * Deg3Heap.java<BR>
 * Definitions for degree-3 heap implementation of an Heap ADT.
 * <P>
 * A binary heap/array implementation of the Heap ADT.<BR>
 * This implementation uses an array (size determined by a parameter
 * to the constructor) to make a binary min-heap of int values,
 * in order to implement the ADT Heap interface.  The "insert" and 
 * "removeMin" methods take O(log n) time, and the "Min", "isEmpty" 
 * and "size" methods take O(1) time.
 * <P>
 * Last Update:  Nov. 5, 2005
 * 
 * NOTE:
 * This file was originally edited from Deg2Heap.javs to allow for
 * a degree-3 heap implementation, and was written by Loren Segal 
 * 5442680 for COMP352 Assignment 3, due November 11th. Due credit
 * goes to the original author of the Deg2Heap.java as well.
 *
 */
 
public class Deg3Heap implements Heap {
	
    ///////////////////////////////////////////////////////////////    
    // Global variables and Constructor
    ///////////////////////////////////////////////////////////////    
 
   /**
    * pointer to the array of int values.
    * Heap values are stored at indices 1 and onwards.
    */
    private int[] array;
	
   /**
    * physical size of the array.
    */
    private int arraySize;
	
   /**
    * number of elements actually stored in the array.
    */
    private int inUse; // index of last element as well.
 
    /**
     *  Constructor.
     *  @param size The minimum number of elements this priority queue
     *  will have to hold.
     */
    public Deg3Heap(int size) {
	size++; // index 0 is not used.
	array = new int[size]; 
	arraySize = size;
	inUse = 0; 
    } // Deg2Heap
 
    ///////////////////////////////////////////////////////////////    
    // Local functions
    ///////////////////////////////////////////////////////////////    
 
    /** 
     * Return leftchild position
     * 
     * @param pos index of the parent.
     * @return index of left child of parent.
     */
    private int leftchild(int pos) { 
	return 3*pos - 1; 
    }    
    
    
 
    /** 
     * Return middlechild position
     * 
     * @param pos index of the parent.
     * @return index of middle child of parent.
     */
    private int middlechild(int pos) { 
	return 3*pos; 
    }       
 
    /** 
     * Return rightchild position
     * 
     * @param pos index of the parent.
     * @return index of right child of parent.
     */
     private int rightchild(int pos) { 
	 return 3*pos + 1; 
     }    
 
    /** 
     * Return parent position
     * 
     * @param pos index of a child.
     * @return index of the parent of the child.
     */
     private int parent(int pos) { 
	 return (pos + 1)/3; 
     }
 
    /**
     * TRUE if pos is a leaf
     * 
     * @param pos index of node being tested.
     * @return boolean value indicating if node is a leaf.
     */
     private boolean isLeaf(int pos) { 
	 return ((pos > inUse/3) && (pos <= inUse)); 
     }
    
    ///////////////////////////////////////////////////////////////    
    // Class methods
    ///////////////////////////////////////////////////////////////    
 
    /**
     * Insert a new value into the priority queue.
     * @param key The key value to insert.
     * @return The inserted key value. 
     */
    public int insert(int key) {
	if (inUse >= arraySize) 
	    System.err.println("Inserting while heap is full");
	if (inUse < arraySize) {
	    inUse++;
	    int curr = inUse;
	    array[curr] = key;  // Start at end of heap
	    // Now sift up until the key of curr's parent <= key of curr
	    while ( (curr > 1)  &&
		    (array[curr] < array[parent(curr)]) ) {
		array[curr] = array[parent(curr)];
		array[parent(curr)] = key; // swap key into parent's spot
		curr = parent(curr); // curr is now the key's location.
	    } // while
	} // if
	return key;
    } // insert
 
    /**
     * Get the minimum value in the priority queue.
     * @return The minimum value.  
     */
    public int min() {
	if (inUse == 0)
	    System.err.println("oops...");
	return array[0];
    } // min
 
    /**
     * Remove the largest key value from the priority queue.
     * @return The removed minimum value. 
     */
    public int removeMin() {
	int minChild;
	int removeKey = array[1]; // root key value
	if (inUse < 1)
	    System.err.println("Removing from empty heap");
	else
	    if (inUse > 1) {
		int curr = 1;
		array[curr] = array[inUse]; // Swap minimum with last value
		inUse--; // one less value.
		// Put new heap root val in correct place
		while (!isLeaf(curr)) {
		    minChild = leftchild(curr);
		    if ( (minChild < inUse) && // if there is a middle child...
			 (array[leftchild(curr)] > array[middlechild(curr)]) )
			minChild = middlechild(curr); 
		    else if ( (minChild < inUse) && // if there is a right child...
			 (array[leftchild(curr)] > array[rightchild(curr)]) )
			minChild = rightchild(curr); 
		    // minChild is now index of child with smaller value
		    if (array[curr] <= array[minChild]) 
			return removeKey; // Done and break out of while loop.
		    int temp = array[curr]; // swap keys
		    array[curr] = array[minChild];
		    array[minChild] = temp;
		    curr = minChild;  // Move down to child
		} // while
	    } // if 
	return removeKey;
    } // removeMin
 
    /**
     * Is the priority queue empty?
     * @return true if and only if the priority queue is empty.
     */
    public boolean isEmpty() {
	return (inUse == 0);
    } // isEmpty
 
    /**
     * Size of the priority queue.
     * @return Number of key values in priority queueu.
     */
    public int size() {
	return inUse;
    } // size
 
    /**
     * Is the priority queue in Min-Heap order? Do not modify the
     * implementation of this method.
     * 
     * @return true if and only if the priority queue is in heap order.
     */
    public boolean testHeap() {
	boolean heapOrder = true;
	for (int i=2; i < inUse+1; i++) {
	    if (array[i] < array[parent(i)]) {
		heapOrder = false;
		// if a problem with order, some diagnostics are printed.
		System.out.println();
		System.out.println("Testing heap order for size = " + inUse);
		System.out.print("i: " + i + ": parent(i) = " + parent(i));
		System.out.print(": heap[i] = " + array[i]);
		System.out.println(": heap[parent(i)] = " + array[parent(i)]);
	    } // ir
	} // for
	if (!heapOrder)
	    System.out.println("Heap is NOT in Min-heap order as expected");
	return heapOrder;
    } // testHeap
 
}