/** * Heap implements a heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ public class LinkedHeap extends LinkedBinaryTree implements HeapADT { public HeapNode lastNode; public LinkedHeap() { super(); } /** * Adds the specified element to this heap in the appropriate * position according to its key value. Note that equal elements * are added to the right. * * @param obj the element to be added to this head */ public void addElement (T obj) { HeapNode node = new HeapNode(obj); if (root == null) root=node; else { HeapNode next_parent = getNextParentAdd(); if (next_parent.left == null) next_parent.left = node; else next_parent.right = node; node.parent = next_parent; } lastNode = node; count++; if (count>1) heapifyAdd(); } /** * Returns the node that will be the parent of the new node * * @return the node that will be a parent of the new node */ private HeapNode getNextParentAdd() { HeapNode result = lastNode; while ((result != root) && (result.parent.left != result)) result = result.parent; if (result != root) if (result.parent.right == null) result = result.parent; else { result = (HeapNode)result.parent.right; while (result.left != null) result = (HeapNode)result.left; } else while (result.left != null) result = (HeapNode)result.left; return result; } /** * Reorders this heap after adding a node. */ private void heapifyAdd() { T temp; HeapNode next = lastNode; temp = next.element; while ((next != root) && (((Comparable)temp).compareTo (next.parent.element) < 0)) { next.element = next.parent.element; next = next.parent; } next.element = temp; } /** * Remove the element with the lowest value in this heap and * returns a reference to it. Throws an EmptyCollectionException * if the heap is empty. * * @return the element with the lowest value in * this heap * @throws EmptyCollectionException if an empty collection exception occurs */ public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); T minElement = root.element; if (count == 1) { root = null; lastNode = null; } else { HeapNode next_last = getNewLastNode(); if (lastNode.parent.left == lastNode) lastNode.parent.left = null; else lastNode.parent.right = null; root.element = lastNode.element; lastNode = next_last; heapifyRemove(); } count--; return minElement; } /** * Reorders this heap after removing the root element. */ private void heapifyRemove() { T temp; HeapNode node = (HeapNode)root; HeapNode left = (HeapNode)node.left; HeapNode right = (HeapNode)node.right; HeapNode next; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right; temp = node.element; while ((next != null) && (((Comparable)next.element).compareTo (temp) < 0)) { node.element = next.element; node = next; left = (HeapNode)node.left; right = (HeapNode)node.right; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right; } node.element = temp; } /** * Returns the node that will be the new last node after a remove. * * @return the node that willbe the new last node after a remove */ private HeapNode getNewLastNode() { HeapNode result = lastNode; while ((result != root) && (result.parent.left == result)) result = result.parent; if (result != root) result = (HeapNode)result.parent.left; while (result.right != null) result = (HeapNode)result.right; return result; } /** * Returns the element with the lowest value in this heap. * Throws an EmptyCollectionException if the heap is empty. * * @return the element with the lowest value in * this heap * @throws EmptyCollectionException if an empty collection exception occurs */ public T findMin () throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); return root.element; } }