Heap.java Source code

Java tutorial

Introduction

Here is the source code for Heap.java

Source

/**
 * Copyright (c) 2008-2010  Morten Silcowitz.
 *
 * This file is part of the Jinngine physics library
 *
 * Jinngine is published under the GPL license, available 
 * at http://www.gnu.org/copyleft/gpl.html. 
 */
//package jinngine.util;
import java.util.*;

/**
 * Minimum heap implementation. See [Cormen et al 1999] for formal theory. 
 * Maintains all elements in a min-heap, such that the minimum element will
 * be the top-most node in the heap at all times. Among many other uses, heaps are ideal for 
 * representing priority queues. 
 */
public class Heap<T> {
    private int size;
    final private List<Node> heap;
    final private Comparator<T> comparator;

    private class Node {
        public T element;
        public int position;
    }

    /**
     * Create a new heap
     * @param comparator A comparator that handles elements of type T
     */
    public Heap(Comparator<T> comparator) {
        size = 0;
        //Allocate space
        heap = new ArrayList<Node>();

        //Comparator
        this.comparator = comparator;

        //initialy clear
        //for (int i=0;i<maxSize;i++) heap[i] = null;
    }

    /**
     * Insert element into the heap. O(lg n) where n is the number of elements/nodes in the heap  
     * @param element new element to be inserted
     */
    public void insert(final T element) {
        size++;
        Node node = new Node();
        node.element = element;
        node.position = size - 1;
        heap.add(node);
        decreaseKey(node);
        //return node;
    }

    public final void clear() {
        heap.clear();
        size = 0;
    }

    /**
     * Return a reference to the top-most element on the heap. The method does not change the state
     * of the heap in any way. O(k).
     * @return Reference to top-most element of heap
     */
    public final T top() {
        return heap.get(0).element;
    }

    //bound check missing

    /**
     * Pop an element of the heap. O(lg n) where n is the number of elements in heap.
     */
    public T pop() {
        T returnNode = top();
        exchange(0, size - 1);
        heap.remove(size - 1);
        size--;

        //if any elements left in heap, do minHeapify
        if (size > 0) {
            minHeapify(heap.get(0));
        }

        return returnNode;
    }

    //  private final void reinsert( final Node n ) {
    //    if ( !decreaseKey(n) ) {
    //      minHeapify(n);
    //    }
    //  }

    public final int size() {
        return size;
    }

    private final boolean decreaseKey(final Node node) {
        int index = node.position;
        boolean modified = false;

        //    while ( index>0 &&  (heap[parent(index)]).compareTo( heap[index]) >= 0 ) {
        while (index > 0 && comparator.compare(heap.get(parent(index)).element, heap.get(index).element) >= 0) {
            exchange(index, parent(index));
            index = parent(index);
            modified = true;
        }

        return modified;
    }

    private final void minHeapify(final Node node) {
        int smallest;
        int index = node.position;
        int left = left(index);
        int right = right(index);

        //  if (left<size && (heap[left]).compareTo(heap[index]) <= 0 )
        if (left < size && comparator.compare(heap.get(left).element, heap.get(index).element) <= 0)
            smallest = left;
        else
            smallest = index;

        //    if (right<size && (heap[right]).compareTo(heap[smallest]) <=0 )
        if (right < size && comparator.compare(heap.get(right).element, heap.get(smallest).element) <= 0)
            smallest = right;
        if (smallest != index) {
            exchange(index, smallest);
            minHeapify(heap.get(smallest));
        }
    }

    private final void exchange(final int index, final int index2) {
        Node temp = heap.get(index);
        temp.position = index2;

        Node temp2 = heap.get(index2);
        temp2.position = index;

        heap.set(index, temp2);
        heap.set(index2, temp);

        //Update posistion in Node
        //    heap.get(index).position=index;
        //    heap.get(index2).position=index2;
    }

    private final int parent(final int i) {
        return i / 2;
    }

    private final int left(final int i) {
        return 2 * i;
    }

    private final int right(final int i) {
        return 2 * i + 1;
    }

    /**
     * Returns an iterator that iterates over all elements of the heap, in no particular order
     * @return
     */
    public final Iterator<T> iterator() {
        return new Iterator<T>() {
            private Iterator<Node> iterator = heap.iterator();

            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public T next() {
                return iterator.next().element;
            }

            @Override
            public void remove() {
            }
        };
    }

    //  public void printHeap() {
    //    int step =1;
    //    int i = 0;
    //    for (int n=0;n<size;n++) {
    //      i++;
    //      //System.out.print(""+ ((Contact)heap[n].item).relativeV + "*");
    //      if (i%step == 0 ) {
    //        step *=2; i=0;
    //        System.out.println("");
    //      }
    //    }
    //
    //    System.out.println("");
    //  }
}