BinaryHeap.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
00020  *
00021  */
00022 
00023 
00024 package utils;
00025 
00026 import java.util.*;
00027 
00028 /*
00029  * A binary heap can be used as a priority queue.
00030  *
00031  * The elements are Object's. They are compared using a Comparator which is passed to
00032  * the constructors of BinaryHeap. The root of the heap is the element which has the smallest key value.
00033  *
00034  * The heap may also contain multiple elements which are "equal" wrt the comparator, i.e., the comparator returns 0
00035  * when comparing those elements. However, a precondition of method add() is that the object instance to be added
00036  * does not yet exist in the heap.
00037  *
00038  */
00039 public class BinaryHeap {
00040     
00041     /*
00042      * IMPORTANT: the logical heap index ranges from 1..size, hence heap[index-1] contains the heap
00043      * element at this index.
00044      */
00045     protected Object[] heap;
00046 
00047     protected int size;
00048     
00049     protected float incrementCapacityFactor;
00050 
00051     protected Comparator comparator;
00052 
00053     /*
00054      * Creates a heap with a size of 0 and the specified initial capacity. The comparator
00055      * is supposed to return -1 for two elements (e1, e2) if e1 has a higher "priority", i.e., if 
00056      * e1 should be closer to the root.
00057      *
00058      * When the heap runs out of capacity, then the capacity is doubled.
00059      */
00060     public BinaryHeap(Comparator comparator, int initialCapacity) {
00061         assert(initialCapacity >= 0);
00062 
00063         heap = new Object[initialCapacity];
00064         incrementCapacityFactor = 1.0f;
00065         size = 0;
00066         this.comparator = comparator;
00067     }
00068 
00069     /*
00070      * An incrementCapacityFactor of, e.g., 0.5 means that, when the heap runs out of capacity,
00071      * the capacity is increased by 50 percent.
00072      */
00073     public BinaryHeap(Comparator comparator, int initialCapacity, float incrementCapacityFactor) {
00074         assert((initialCapacity >= 0) && (incrementCapacityFactor > 0));
00075 
00076         heap = new Object[initialCapacity];
00077         this.incrementCapacityFactor = incrementCapacityFactor;
00078         size = 0;
00079         this.comparator = comparator;
00080     }
00081 
00082     public int getCapacity() {
00083         return heap.length;
00084     }
00085 
00086     /*
00087      * The actual number of elements in the heap.
00088      */
00089     public int size() {
00090         return size;
00091     }
00092 
00093     protected void incrementCapacity() {
00094         //assert(invariant());
00095 
00096         int newCap = Math.round(getCapacity() * (1 + incrementCapacityFactor));
00097         
00098         Object[] newHeap = new Object[newCap];
00099         System.arraycopy(heap, 0, newHeap, 0, size);
00100         heap = newHeap;
00101 
00102         //assert(invariant());
00103     }
00104 
00105     public String toString() {
00106         String result = "";
00107 
00108         Iterator it = iterator();
00109         while (it.hasNext()) {
00110             Object o = it.next();
00111             result = result += o.toString();
00112             if (it.hasNext()) result += " | ";
00113         }
00114 
00115         return result;
00116     }
00117 
00118     protected boolean invariant() {
00119         for (int i = 1; i < size / 2; ++i) {
00120             if (!invariant(i)) {
00121                 System.out.println("BinaryHeap: invariant failed for element " + i + "; size = " + size);
00122                 //System.out.println("[" + this + "]");
00123                 return false;
00124             }
00125         }
00126         return true;
00127     }
00128 
00129     /*
00130      * Checks if the parent value of the heap element at index is smaller than its children.
00131      *
00132      * Remember, again, that heap[index-1] contains the heap element at index (which ranges from 1..size).
00133      */
00134     protected boolean invariant(int index) {
00135         assert((index >= 1) && (index <= size));
00136         
00137         for (int i = 1; i <= size; ++i) {
00138             if (heap[i - 1] == null) {
00139                 System.out.println("There is a null value in the heap!!!");
00140                 return false;
00141             }
00142         }
00143 
00144         int left = index * 2;
00145         if (left <= size) {
00146             if (comparator.compare(heap[index - 1], heap[left - 1]) > 0) {
00147                 System.out.println("heap[index - 1] > heap[left - 1]) > 0 !!!");
00148                 return false;
00149             } else {
00150                 int right = index * 2 + 1;
00151                 if (right <= size) {
00152                     if (comparator.compare(heap[index - 1], heap[right - 1]) > 0) {
00153                         System.out.println("heap[index - 1] > heap[right - 1]) !!!");
00154                         System.out.println("heap[index - 1]:  " + heap[index - 1]
00155                                            + "\nheap[right - 1]: " + heap[right - 1]);
00156                         return false;
00157                     }
00158                 }
00159             }
00160         }
00161 
00162         return true;
00163     }
00164 
00165     public void add(Object newObj) {
00166         assert((newObj != null) && !contains(newObj));
00167         //assert(invariant());
00168 
00169         if (size + 1 > heap.length) {
00170             incrementCapacity();
00171             assert(size + 1 <= heap.length);
00172         }
00173 
00174         ++size;
00175         heap[size - 1] = newObj;
00176         
00177         int i = size;
00178         while (i > 1) {
00179 
00180             int parent = i / 2;
00181             int comp = comparator.compare(heap[parent - 1], heap[i - 1]);
00182 
00183             if (comp > 0) {
00184 
00185                 //assert(invariant(i));
00186                 swap(parent, i);
00187                 //assert(invariant(parent));
00188 
00189                 //assert(invariant(i));
00190 
00191                 i = parent;
00192             } else {
00193 
00194                 //assert(invariant(parent));
00195                 //assert(invariant(i));
00196                 break;
00197             }
00198         }
00199 
00200         //assert(invariant());
00201     }
00202 
00203     /*
00204      * Iterates through the Object's in the heap; the order in which the elements are iterates is not guaranteed.
00205      */
00206     public Iterator iterator() {
00207         return new BinaryHeapIterator();
00208     }
00209 
00210     public Object removeMin() {
00211 
00212         assert(size >= 1);
00213         //assert(invariant());
00214 
00215         Object result = heap[1 - 1];  // :)
00216         int oldSize = size;
00217         --size;
00218 
00219         if (size > 0) {
00220             int i = 1;
00221             Object lastElem = heap[oldSize - 1];
00222             heap[0] = lastElem;
00223             heap[oldSize - 1] = null;
00224 
00225             while (i < size) {
00226                 int left = i * 2;
00227                 if (left > size) {  // there is no left element
00228                     //assert(invariant(i));
00229                     break;
00230                 
00231                 } else {  // there is a left element
00232                     assert(heap[left - 1] != null);
00233 
00234                     int right = left + 1;
00235                     if (right <= size) {  // there is a left and a right element
00236                         assert((heap[left - 1] != null) && (heap[right - 1] != null));
00237 
00238                         int smaller;
00239                         if (comparator.compare(heap[left - 1], heap[right - 1]) < 0) smaller = left;
00240                         else smaller = right;
00241                         
00242                         if (comparator.compare(heap[i - 1], heap[smaller - 1]) > 0) {
00243                             swap(i, smaller);
00244                             i = smaller;
00245                         } else break;
00246                         
00247                     } else {  // there is only a left element
00248                         assert(heap[left - 1] != null);
00249 
00250                         if (comparator.compare(heap[i - 1], heap[left - 1]) > 0) {
00251                             swap(i, left);
00252                             i = left;
00253                         } else break;
00254 
00255                     }
00256                 }
00257             
00258             } 
00259 
00260             assert(contains(lastElem, 1, size));
00261         
00262         } else {
00263             heap[0] = null;
00264         }
00265         
00266         assert(!contains(result, 1, size));         
00267 
00268         //assert(invariant());
00269         return result;
00270     
00271     }  // removeMin()
00272 
00273     protected boolean contains(Object obj) {
00274         return contains(obj, 1, size);
00275     }
00276 
00277     protected boolean contains(Object obj, int start, int end) {
00278         for (int i = start; i <= end; ++i) {
00279             if (heap[i - 1] == obj) return true;
00280         }
00281 
00282         return false;
00283     }
00284 
00285     protected void swap(int index1, int index2) {
00286         assert(index1 != index2);
00287         assert((heap[index1 - 1] != null) && (heap[index2 - 1] != null));
00288         
00289         Object tmp = heap[index1 - 1];
00290         heap[index1 - 1] = heap[index2 - 1];
00291         heap[index2 - 1] = tmp;
00292     }
00293 
00294     protected class BinaryHeapIterator implements Iterator {
00295         
00296         int next;
00297 
00298         public BinaryHeapIterator() {
00299             next = 1;
00300         }
00301 
00302         public boolean hasNext() {
00303             return (next <= size);
00304         }
00305 
00306         public Object next() {
00307             assert(hasNext());
00308             Object result = heap[next - 1];
00309             ++next;
00310             return result;
00311         }
00312 
00313         public void remove() {
00314             throw new UnsupportedOperationException();
00315         }
00316 
00317     }
00318 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16