import java.util.Vector; /** * A Heap. See notes for more details. */ public class Heap { // +--------+-------------------------------------------------- // | Fields | // +--------+ /** * All the elements in the heap. */ Vector elements; /** * The comparator used to decide where things go. */ GComparator compare; /** * The length of the heap. */ int length; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Create a new heap. */ public Heap(GComparator compare) { this.compare = compare; this.elements = new Vector(); this.length = 0; } // Heap(GComparator) // +---------+------------------------------------------------- // | Methods | // +---------+ /** * Add a new element to the heap. */ public void add(Object newElement) { this.elements.add(newElement); swapUp(this.length); ++this.length; } // add(Object newElement) /** * Delete and return the smallest element in the heap. */ public Object deleteSmallest() { // Remember the smallest element. Object smallest = this.elements.get(0); // Shove the rightmost element into the root --this.length; this.elements.set(0, this.elements.get(this.length)); this.elements.remove(this.length); // Swap the element down to the right place. swapDown(0); // Return the smallest element. return smallest; } // deleteSmallest() void swapDown(int pos) { // Case 1: No children. Done. if (left(pos) >= this.length) return; // Case 2: Only one child. Swap if necessary. else if (right(pos) >= this.length) { if (compare.mayPrecede(this.elements.get(left(pos)), this.elements.get(pos))) { swap(pos, left(pos)); swapDown(left(pos)); } // Element at pos is greater than left child. } // Only one child // Case 3: Two children, the leftmost is smaller ... else if (compare.mayPrecede(this.elements.get(left(pos)), this.elements.get(right(pos)))) { if (compare.mayPrecede(this.elements.get(left(pos)), this.elements.get(pos))) { swap(pos, left(pos)); swapDown(left(pos)); } // Element at pos is greater than left child. } // two children, leftmost smaller // Case 4: Two children, rightmost is smaller. else { if (compare.mayPrecede(this.elements.get(right(pos)), this.elements.get(pos))) { swap(pos, right(pos)); swapDown(right(pos)); } // Element at pos is greater than left child. } // two children, rightmost smaller } // swapDown void swapUp(int pos) { if (pos <= 0) return; if (compare.mayPrecede(this.elements.get(pos), this.elements.get(parent(pos)))) { swap(pos, parent(pos)); swapUp(parent(pos)); } } // swapUp(int) /** * Dump the heap to the screen. */ public void dump() { dump(0, ""); } // dump() void dump(int pos, String indent) { if (pos < length) { System.out.println(indent + elements.get(pos)); dump(left(pos), indent + "L "); dump(right(pos), indent + "R "); } } // dump(int, String) void swap(int x, int y) { Object temp = elements.get(x); elements.set(x, elements.get(y)); elements.set(y, temp); } // swap(int, int) int parent(int pos) { return (pos-1)/2; } int left(int pos) { return 2*pos + 1; } int right(int pos) { return 2*pos + 2; } } // class Heap