package u6; import utils.*; import java.util.*; /** * Array based implementation of Heap Data Structure. * The nodes of binary tree of the heap are stored in a lenear structure. * * @author V.Boutchkova * @version 2.3.1 Nov 2001 */ public class ArrayHeap extends Heap { /** Heap container */ private ArrayList elements; /** Constructs an empty heap with the specified comparator */ public ArrayHeap(Comparator cmp) { super(cmp); elements = new ArrayList(); } /** * Bottom-Up construction. * Constructs a heap and fills it with the objects from items * using an algorithm for bottom-up construction. */ public ArrayHeap(Comparator comparator, Item[] items) { super(comparator); size = items.length; height = computeHeight(size); elements = new ArrayList(size); for (int i = 0; i < size; i++) { elements.add(items[i]); } bottomUp(0); } /** * Constructs the items of the subarray starting from loInx, i.e. * items[sInx..size - 1] into the heap container. */ public void bottomUp(int sInx) { if (sInx + 1 >= elements.size()) return; bottomUp(getLeft(sInx)); bottomUp(getRight(sInx)); downBubbling(sInx); } /** * Adds the given item in the heap and updates the * size and the height values. */ public void add(Item entry) { elements.add(entry); size++; if ((size == (2 << (height - 1))) || (size == 1)) { height++; } upBubbling(); } /** * Extracts the root of the Heap and updates the * size and the height values. */ public Item extractItem() { swap(0, size - 1); Item result = (Item) elements.remove(size - 1); size--; if ((size + 1 == (2 << (height - 2))) || (size <= 1)) { height--; } downBubbling(); return result; } /** Reads the key, stored in the root of the heap, without extracting the root. */ public Object readMinKey() { return ((Item) elements.get(0)).getKey(); } /** * Reads the element value of the item, stored in the root of the heap * without removing the root. */ public Object readMinElement() { return ((Item) elements.get(0)).getValue(); } /** * Restores the order-property of the heap, * in the case it's violated by the last node. */ protected void upBubbling() { upBubbling(size - 1); } /** * Restores the order-property of the heap, * in the case it's violated by the root. */ protected void downBubbling() { downBubbling(0); } /** * Locally restores the order-property at the node with the * given (absolute) index. */ protected void upBubbling(int index) { if (index == 0) return; int parentIndex = getParent(index); if (cmp.compare(((Item)elements.get(parentIndex)).getKey(), ((Item)elements.get(index)).getKey()) > 0) { swap(parentIndex, index); upBubbling(parentIndex); } } /** * Locally restores the order-property at the node with the * given (absolute) index and the given last node. */ protected void downBubbling(int index) { if ((index >= size) || (getLeft(index) >= size)) return; Item node = (Item) elements.get(index); Item min = (Item) elements.get(getLeft(index)); int minIndex = getLeft(index); if (getRight(index) < size) { Item right = (Item) elements.get(getRight(index)); if (cmp.compare(min.getKey(), right.getKey()) > 0) { min = right; minIndex = getRight(index); } } if (cmp.compare(node.getKey(), min.getKey()) > 0) { swap(index, minIndex); downBubbling(minIndex); } } /** Swaps the elements with index i and j. */ protected void swap(int i, int j) { Object tmp = elements.get(i); elements.set(i, elements.get(j)); elements.set(j, tmp); } /** * Calculates the position of the left child * of the element with the given index. */ private int getLeft(int index) { return 2 * index + 1; } /** * Calculates the position of the right child * of the element with the given index. */ private int getRight(int index) { return 2 * index + 2; } /** Calculates the position of the parent of the element with the given index. */ private int getParent(int index) { return (index - 1) / 2; } public Object[] toArray(Object[] a) { return elements.toArray(a); } }