Heap.java

Download
1/*2 * Heap.java3 *4 * Computer Science S-22, Harvard University5 */6 7import java.util.*;8 9/**10 * Heap - a generic collection class that implements 11 * a max-at-top heap using an array12 */13public class Heap<T extends Comparable<T>> {14    private T[] contents;15    private int numItems;16    17    public Heap(int maxSize) {18        contents = (T[])new Comparable[maxSize];19        numItems = 0;20    }21    22    public Heap(T[] arr) {23        // Note that we don't copy the array, so that heapsort can24        // sort the array in place.25        contents = arr;26        numItems = arr.length;27        makeHeap();28    }29    30    /* 31     * makeHeap - turn the elements in the contents array into a32     * representation of a max-at-top heap.33     */34    private void makeHeap() {35        int last = contents.length - 1;36        int parentOfLast = (last - 1)/2;37        for (int i = parentOfLast; i >= 0; i--)38            siftDown(i);39    }40    41    /** 42     * insert - add the specified item to the heap and sift it up43     * into its proper position.44     */45    public void insert(T item) {46        if (numItems == contents.length) {47            // grow the array48            T[] newContents = (T[])new Comparable[contents.length * 2];49            System.arraycopy(contents, 0, newContents, 0, numItems);50            contents = newContents;51        }52        53        contents[numItems] = item;54        siftUp(numItems);55        numItems++;56    }57    58    /**59     * remove and return the item at the top of the heap, and adjust60     * the remaining items so that we still have a heap.61     */62    public T remove() {63        if (numItems == 0) {64            throw new NoSuchElementException();65        }66        67        T toRemove = contents[0];68        69        // Move the element currently the end of the heap to the top70        // and sift it into place.71        contents[0] = contents[numItems - 1];72        contents[numItems - 1] = null;73        numItems--;74        siftDown(0);75        76        return toRemove;77    }78    79    /**80     * isEmpty - does the heap currently have no items?81     */82    public boolean isEmpty() {83        return (numItems == 0);84    }85    86    /**87     * toString - create a string representation of the heap of the form88     * { ( root ) ( items in level 1 ) ( items in level 2 ) ... }89     */90    public String toString() {91        String str = "{ ";92        93        int start = 0;94        int levelSize = 1;95        while (start < numItems) {96            // print all of the items at the current level of the tree97            str += "( ";98            for (int i = start; i < start + levelSize && i < numItems; i++)99                str += (contents[i] + " ");100            str += ") ";101            102            // move down to the next level103            start += levelSize;104            levelSize *= 2;105        }106        107        str += "}";108        return str;109    }110    111    /*112     * siftDown - sift the element in contents[i] down into its113     * correct position in the heap.114     */115    private void siftDown(int i) {116        // Store a reference to the element being sifted.117        T toSift = contents[i];118        119        // Find where the sifted element belongs.120        int parent = i;121        int child = 2 * parent + 1;122        while (child < numItems) {123            // If the right child is bigger, compare with it.124            if (child < numItems - 1  &&125                contents[child].compareTo(contents[child + 1]) < 0)126                child = child + 1;127            128            // Check if we're done.129            if (toSift.compareTo(contents[child]) >= 0)130                break;131            132            // If not, move child up and move down one level in the tree.133            contents[parent] = contents[child];134            parent = child;135            child = 2 * parent + 1;136        }137        138        contents[parent] = toSift;139    }140    141    /*142     * siftUp - sift the element in contents[i] up into its143     * correct position in the heap.144     */145    private void siftUp(int i) {146        // Store a reference to the element being sifted.147        T toSift = contents[i];148        149        // Find where the sifted element belongs.150        int child = i;151        while (child > 0) {152            int parent = (child - 1)/2;153            154            // Check if we're done.155            if (toSift.compareTo(contents[parent]) <= 0)156                break;157            158            // If not, move parent down and move up one level in the tree.159            contents[child] = contents[parent];160            child = parent;161        }162        163        contents[child] = toSift;164    }165    166    public static void main(String[] args) {167        String commandString = "";168        Scanner in = new Scanner(System.in);169        170        System.out.print("max size: ");171        int maxSize = in.nextInt();172        in.nextLine();    // consume the rest of the line173        Heap<Integer> heap = new Heap<Integer>(maxSize);174        175        while(true) {176            System.out.println(heap);177            System.out.println();178            179            do {180                System.out.print("[I]nsert int | [R]emove | [Q]uit : ");181                commandString = in.nextLine();182            } while (commandString.length() == 0); 183            184            Scanner command = new Scanner(commandString);185            String commandChar = command.next();186            187            try {188                if (commandChar.equalsIgnoreCase("q"))189                    System.exit(1);190                else if (commandChar.equalsIgnoreCase("i")) {191                    // insert192                    int item = command.nextInt();193                    heap.insert(item);194                } else if (commandChar.equalsIgnoreCase("r")) {195                    // remove (and isEmpty)196                    if (heap.isEmpty())197                        System.out.println("Heap is empty.");198                    else 199                        System.out.println("Removed: " + heap.remove());200                } else201                    System.out.println("Invalid command: " + commandString);202            } catch (NoSuchElementException e) {203                System.out.println("Invalid command: " + commandString);204            }205        }206    }207}