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 }