1package ds.persistent.queue;
2
3
4
5
6
7
8
9
10
11
12import ds.interfaces.PriorityQueue;
13
14import ds.util.P;
15import ds.util.V;
16import ds.util.PV;
17
18import static ds.util.PV.mkPair;
19import static ds.util.Integer.max;
20import static ds.util.Integer.min;
21import static ds.util.Undef.undefined;
22
23import java.util.Iterator;
24
25import static java.lang.Integer.signum;
26
27
28
29public abstract
30 class BinaryHeap
31 implements PriorityQueue {
32
33
34
35
36
37 public static
38 BinaryHeap empty() {
39 return
40 EMPTY;
41 }
42
43
44 public static
45 BinaryHeap singleton(P p, V v) {
46 return
47 new Node(p, v, EMPTY, EMPTY);
48 }
49
50
51 public static
52 BinaryHeap fromIterator(Iterator<PV> elems) {
53
54 BinaryHeap res = empty();
55 while ( elems.hasNext() ) {
56 PV p = elems.next();
57 res = res.insert(p.fst, p.snd);
58 }
59 return
60 res;
61 }
62
63
64
65
66 public abstract BinaryHeap insert(P p, V v);
67 public abstract BinaryHeap removeMin();
68
69 public String toString() {
70 return
71 iterator().toString();
72 }
73
74 public Iterator<PV> iterator() {
75 return
76 new HeapIterator(this);
77 }
78
79 public BinaryHeap copy() {
80 return
81 this;
82 }
83
84
85
86
87 abstract public int depth();
88 abstract public int minDepth();
89
90
91
92
93
94 abstract boolean childGE(P p);
95
96 abstract BinaryHeap merge(BinaryHeap h2);
97 abstract BinaryHeap merge2(Node n1);
98
99 private static <A> A nodeExpected() {
100 return
101 undefined("Node expected");
102 }
103
104
105
106
107
108
109
110 private static final BinaryHeap EMPTY
111 = new Empty();
112
113
114
115 private static final
116 class Empty
117 extends BinaryHeap {
118
119
120 public boolean isEmpty() {
121 return true;
122 }
123
124 public int size() {
125 return 0;
126 }
127
128 public int depth() {
129 return 0;
130 }
131
132 public int minDepth() {
133 return 0;
134 }
135
136 public PV findMin() {
137 return nodeExpected();
138 }
139
140 public BinaryHeap insert(P p, V v) {
141 return
142 singleton(p, v);
143 }
144
145 public BinaryHeap removeMin() {
146 return nodeExpected();
147 }
148
149 public boolean inv() {
150 return true;
151 }
152
153
154
155
156 Empty() { }
157
158 boolean childGE(P p) {
159 return true;
160 }
161
162 BinaryHeap merge(BinaryHeap h2) {
163 return h2;
164 }
165 BinaryHeap merge2(Node n1) {
166 return n1;
167 }
168
169 }
170
171
172
173
174 private static final
175 class Node
176 extends BinaryHeap {
177
178
179 final P p;
180 final V v;
181 final BinaryHeap l;
182 final BinaryHeap r;
183
184
185
186
187
188
189
190
191 Node(P p, V v, BinaryHeap l, BinaryHeap r) {
192 assert p != null;
193
194 this.p = p;
195 this.v = v;
196 this.l = l;
197 this.r = r;
198 ++cntNode;
199 }
200
201
202
203
204 public boolean isEmpty() {
205 return false;
206 }
207
208 public int size() {
209 return
210 1 + l.size() + r.size();
211 }
212
213 public int depth() {
214 return
215 1 + max(l.depth(), r.depth());
216 }
217
218 public int minDepth() {
219 return
220 1 + min(l.minDepth(), r.minDepth());
221 }
222
223 public PV findMin() {
224 return
225 mkPair(p, v);
226 }
227
228 public BinaryHeap insert(P p, V v) {
229 return
230 this.merge(singleton(p, v));
231 }
232
233 public BinaryHeap removeMin() {
234
235 return
236 l.merge(r);
237 }
238
239
240
241
242
243
244
245
246
247
248 public boolean inv() {
249 return
250 l.childGE(p)
251 &&
252 r.childGE(p)
253 &&
254 l.inv()
255 &&
256 r.inv();
257 }
258
259
260
261
262
263 boolean childGE(P p) {
264 return
265 this.p.compareTo(p) >= 0;
266 }
267
268
269
270
271
272 BinaryHeap merge(BinaryHeap h2) {
273 return
274 h2.merge2(this);
275 }
276
277 BinaryHeap merge2(Node n1) {
278 if ( this.p.compareTo(n1.p) <= 0)
279 return
280 this.join(n1);
281 return
282 n1.join(this);
283 }
284
285 BinaryHeap join(Node n2) {
286 return
287 setLR(this.r, this.l.merge(n2));
288 }
289
290
291
292 private Node setLR(BinaryHeap l, BinaryHeap r) {
293
294 if ( l == this.l && r == this.r )
295 return
296 this;
297 return
298 new Node(this.p, this.v, l, r);
299
300
301
302
303
304
305
306 }
307
308 }
309
310
311
312
313
314 private static
315 class HeapIterator
316 extends ds.util.Iterator<PV> {
317
318 BinaryHeap queue;
319
320 HeapIterator(BinaryHeap n) {
321
322 queue = n;
323
324
325
326
327
328
329
330 ++cntIter;
331 }
332
333 public boolean hasNext() {
334 return
335 ! queue.isEmpty();
336 }
337
338 public PV next() {
339 if ( queue.isEmpty() )
340 return
341 undefined("empty heap");
342
343 PV res = queue.findMin();
344 queue = queue.removeMin();
345 return
346 res;
347 }
348 }
349
350
351
352
353 private static int cntNode = 0;
354 private static int cntIter = 0;
355
356 public static String stats() {
357 return
358 "stats for ds.persistent.queue.BinaryHeap:\n" +
359 "# new Node() : " + cntNode + "\n" +
360 "# new Iterator() : " + cntIter + "\n";
361 }
362
363 public String objStats() {
364 int s = size();
365 int o = s;
366 int f = 4 * s;
367 int m = o + f;
368
369 return
370 "mem stats for ds.persistent.queue.BinaryHeap object:\n" +
371 "# elements (size) : " + s + "\n" +
372 "# objects : " + o + "\n" +
373 "# fields : " + f + "\n" +
374 "# mem words : " + m + "\n";
375 }
376}