// package Trees; import java.util.*; /** * Heap.java * * * Created: Thu Apr 10 16:02:19 2003 * * @author <a href="mailto:shapiro@cse.buffalo.edu">Stuart C. Shapiro</a> * based on Riley Sect. 9.7 */ public class Heap extends ArrayList { /** * Creates a new empty <code>Heap</code>. * */ public Heap (){ super(); } /** * Creates a new <code>Heap</code> containing all the elements of * the array <code>a</code> value * * @param a the <code>int[]</code> whose elements are to be the * elements of this heap. */ public Heap (int[] a){ super(); for (int i = 0; i < a.length; i++) { add(new Integer(a[i])); } makeHeap(); } /** * Makes this ArrayList into a true Heap. * */ public void makeHeap() { for (int next = 1; next < size(); next++) { promote(next); } } /** * Promotes the value in position ndx of the array representation * of this Heap up to its rightful position in its branch. * */ public void promote(int ndx) { Comparable temp = (Comparable)get(ndx); int insertionPoint = ndx; int j = (ndx - 1) / 2; // points to parent while (j > 0 && temp.compareTo(get(j)) > 0) { set(insertionPoint, get(j)); insertionPoint = j; j = (j - 1) / 2; } // end of while (j > 0 && temp.compareTo(get(j)) > 0) // j == 0 || temp.compareTo(get(j)) < 0 if (temp.compareTo(get(j)) < 0) { set(insertionPoint, temp); } else { // j == 0 && temp.compareTo(get(0)) > 0 set(insertionPoint, get(0)); set(0, temp); } // end of else } /** * Inserts <code>obj</code> into its proper position in this heap. * * @param obj the <code>Comparable</code> object to be inserted. */ public void insert(Comparable obj) { add(obj); promote(size()-1); } /** * Returns the first (greatest) element of this heap. * * @return the first (greatest) element of this heap. */ public Comparable first() { return (Comparable)get(0); } /** * Deletes and returns the first element of this heap. * * @return the deleted element of this heap. */ public Comparable delete() { Comparable oldFirst = first(); int oldLast = size()-1; if (oldLast > 0) { Comparable temp = (Comparable)get(oldLast); int insertionPoint = 0; int maxPointer = indexOfMax(insertionPoint, oldLast); while (maxPointer<oldLast && temp.compareTo(get(maxPointer)) < 0) { set(insertionPoint, (Comparable)get(maxPointer)); insertionPoint = maxPointer; maxPointer = indexOfMax(insertionPoint, oldLast); } // end of while (indexOfMax<oldLast && temp.compareTo(get(maxPointer)) < 0) set(insertionPoint,temp); } // end of if (oldLast > 0) remove(oldLast); return oldFirst; } /** * Returns the index of the maximum of the following elements of * this heap: * 1) the element pointed to by tempPointer; * 2) the left child of parent, if it exists; * 3) the right child of parent, if it exists. * * @param parent an <code>int</code> value * @param tempPointer an <code>int</code> value * @return the index of the element that may be put into parent's * position. */ private int indexOfMax(int parent, int tempPointer) { if (2*parent+1 >= size()) { // parent is leaf return tempPointer; } // end of if (2*parent+1 >= size()) if (2*parent+2 >= size()) { // parent only has left child return maxPointer(2*parent+1, tempPointer); } // end of if (2*parent+2 >= size()) // parent has two children return maxPointer(2*parent+1, maxPointer(2*parent+2, tempPointer)); } /** * Returns whichever index, i or j, points to the larger element * of this heap. * * @param i an <code>int</code> value * @param j an <code>int</code> value * @return whichever index, i or j, points to the larger element * of this heap. */ private int maxPointer(int i, int j) { return ((Comparable)get(i)).compareTo((Comparable)get(j)) > 0 ? i : j; } /** * Returns a <code>String</code> representation of this heap, * whose last node is in index max, starting at index i. * * @param i the index of the root of this subheap. * @param max the index of the last node in this heap. * @return a <code>String</code> representation of this heap, * whose last node is in index max, starting at index i. */ public String heapString(int i, int max) { if (i > max) { return "()"; // empty } // end of if (i > max) if (2*i+1 > max) { return "(" + get(i) + ")"; // leaf } // end of if (2*i+1 > max) return "(" + get(i) + " " + heapString(2*i+1, max) + " " + heapString(2*i+2, max) + ")"; } /** * Returns a <code>String</code> representation of this heap. * * @return a <code>String</code> representation of this heap. */ public String toString() { return heapString(0, size()-1); } /** * Uses heap sort to sort an integer array. * * @param a the <code>int[]</code> to be sorted. */ public static void heapSort(int[] a) { /* Heap sort can really be done in place. * This is just an example. */ Heap heap = new Heap(a); for (int i = a.length-1; i>=0; i--) { a[i] = ((Integer)heap.delete()).intValue(); } } /** * Returns a <code>String</code> representation of the arrray <code>a</code>. * * @param a the <code>int[]</code> whose <code>String</code> * representation is to be returned. * @return a <code>String</code> representation of the arrray <code>a</code>. */ public static String arrayToString (int[] a) { String result = "["; for (int i=0; i<a.length-1; i++) { result += a[i] + ","; } // end of for (int i=0; i<a.length; i++) return result + a[a.length-1] + "]"; } /** * Tests the Heap class. * * @param args a <code>String[]</code> value */ public static void main (String[] args) { int[] a = {2,3,6,1,4,8,0,7}; System.out.println ("Array: " + arrayToString(a)); Heap heap = new Heap(a); System.out.println ("Heap: " + heap); heap.insert(new Integer(5)); System.out.println ("After inserting 5: " + heap); System.out.println("The first element is " + heap.first()); System.out.println("The deleted first element :" + heap.delete()); System.out.println("After deleting the first element :" + heap); heapSort(a); System.out.println("Sorted Array: " + arrayToString(a)); } // end of main () }// Heap