Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 package utils;
00025 
00026 import java.util.*;
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 public class BinaryHeap {
00040     
00041     
00042 
00043 
00044 
00045     protected Object[] heap;
00046 
00047     protected int size;
00048     
00049     protected float incrementCapacityFactor;
00050 
00051     protected Comparator comparator;
00052 
00053     
00054 
00055 
00056 
00057 
00058 
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 
00071 
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 
00088 
00089     public int size() {
00090         return size;
00091     }
00092 
00093     protected void incrementCapacity() {
00094         
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         
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                 
00123                 return false;
00124             }
00125         }
00126         return true;
00127     }
00128 
00129     
00130 
00131 
00132 
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         
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                 
00186                 swap(parent, i);
00187                 
00188 
00189                 
00190 
00191                 i = parent;
00192             } else {
00193 
00194                 
00195                 
00196                 break;
00197             }
00198         }
00199 
00200         
00201     }
00202 
00203     
00204 
00205 
00206     public Iterator iterator() {
00207         return new BinaryHeapIterator();
00208     }
00209 
00210     public Object removeMin() {
00211 
00212         assert(size >= 1);
00213         
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) {  
00228                     
00229                     break;
00230                 
00231                 } else {  
00232                     assert(heap[left - 1] != null);
00233 
00234                     int right = left + 1;
00235                     if (right <= size) {  
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 {  
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         
00269         return result;
00270     
00271     }  
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 }