1package ds.persistent.map;
2
3
4
5
6
7
8
9
10
11
12import ds.interfaces.Map;
13
14import ds.util.K;
15import ds.util.V;
16import ds.util.KV;
17import ds.util.Queue;
18import ds.util.Function2;
19import ds.util.NullIterator;
20
21import static ds.util.KV.mkPair;
22import static ds.util.Integer.max;
23import static ds.util.Integer.min;
24import static ds.util.Undef.undefined;
25
26import java.util.Iterator;
27
28import static java.lang.Integer.signum;
29
30
31
32public abstract
33 class BinaryTree
34 implements Map {
35
36
37
38
39
40 public static
41 BinaryTree empty() {
42 return
43 EMPTY;
44 }
45
46
47 public static
48 BinaryTree singleton(K k, V v) {
49 return
50 new Node(k, v, EMPTY, EMPTY);
51 }
52
53
54 public static
55 BinaryTree fromIterator(Iterator<KV> elems) {
56
57 BinaryTree res = empty();
58 while ( elems.hasNext() ) {
59 KV p = elems.next();
60 res = res.insert(p.fst, p.snd);
61 }
62 return
63 res;
64 }
65
66
67
68
69
70 public static
71 BinaryTree rebuild(Iterator<KV> elems, int len) {
72
73 if ( len == 0 )
74 return EMPTY;
75
76 int lenL = len / 2;
77 int lenR = len - lenL - 1;
78
79 BinaryTree l = rebuild(elems, lenL);
80 KV p = elems.next();
81 BinaryTree r = rebuild(elems, lenR);
82
83 return
84 new Node(p.fst, p.snd, l, r);
85 }
86
87
88
89
90 public abstract BinaryTree insert(K k, V v);
91 public abstract BinaryTree remove(K k);
92
93 public boolean member(K k) {
94 return
95 lookup(k) != null;
96 }
97
98 public BinaryTree
99 union(Map m2) {
100 return
101 unionWith(const2, m2);
102 }
103
104
105
106
107 public BinaryTree
108 unionWith(Function2<V,V,V> op,
109 Map m2) {
110 Iterator<KV> i = m2.iterator();
111 BinaryTree res = this;
112
113 while ( i.hasNext() ) {
114 KV kv2 = i.next();
115 K k2 = kv2.fst;
116 V v2 = kv2.snd;
117 V v1 = res.lookup(k2);
118 V vr = v1 == null ? v2 : op.apply(v1, v2);
119 res = res.insert(k2, vr);
120 }
121 return
122 res;
123 }
124
125 public BinaryTree
126 difference(Map m2) {
127 return
128 differenceWith(null2, m2);
129 }
130
131 public BinaryTree
132 differenceWith(Function2<V,V,V> op,
133 Map m2) {
134
135
136
137 Iterator<KV> i = m2.iterator();
138 BinaryTree res = this;
139
140 while ( i.hasNext() ) {
141 KV kv2 = i.next();
142 K k2 = kv2.fst;
143 V v2 = kv2.snd;
144 V v1 = res.lookup(k2);
145
146 if ( v1 != null ) {
147 V vr = op.apply(v1, v2);
148 if ( vr == null )
149 res = res.remove(k2);
150 else
151 res = res.insert(k2, vr);
152 }
153 }
154 return
155 res;
156 }
157
158 public String toString() {
159 return
160 iterator().toString();
161 }
162
163 public BinaryTree copy() {
164 return
165 this;
166 }
167
168
169
170
171 abstract public int depth();
172 abstract public int minDepth();
173
174 public boolean balanced() {
175 return
176 depth() <= minDepth() + 1;
177 }
178
179 public BinaryTree balance() {
180 return
181 rebuild(iterator(), size());
182 }
183
184
185 abstract public Iterator<KV> iteratorDesc();
186
187 abstract public Iterator<KV> iteratorBreadthFirst();
188
189 public KV findRoot() {
190 return nodeExpected();
191 }
192
193
194
195
196
197 Node node() { return nodeExpected(); }
198 K key() { return nodeExpected(); }
199 V value() { return nodeExpected(); }
200 BinaryTree left() { return nodeExpected(); }
201 BinaryTree right() { return nodeExpected(); }
202
203
204 abstract boolean allLS(K k);
205 abstract boolean allGT(K k);
206
207
208
209
210
211 abstract Node splitAt(K k);
212
213 private static <A> A nodeExpected() {
214 return
215 undefined("Node expected");
216 }
217
218
219 private static Function2<V,V,V> const2
220 = new Function2<V,V,V>() {
221 public V apply(V x, V y) {
222 return y;
223 }
224 };
225
226 private static Function2<V,V,V> null2
227 = new Function2<V,V,V>() {
228 public V apply(V x, V y) {
229 return null;
230 }
231 };
232
233
234
235
236
237
238
239 private static final BinaryTree EMPTY
240 = new Empty();
241
242
243
244 private static final
245 class Empty
246 extends BinaryTree {
247
248
249 public boolean isEmpty() {
250 return true;
251 }
252
253 public int size() {
254 return 0;
255 }
256
257 public int depth() {
258 return 0;
259 }
260
261 public int minDepth() {
262 return 0;
263 }
264
265 public V lookup(K k) {
266 return null;
267 }
268
269 public KV findMin() {
270 return nodeExpected();
271 }
272
273 public KV findMax() {
274 return nodeExpected();
275 }
276
277 public boolean inv() {
278 return true;
279 }
280
281 public Iterator<KV> iterator() {
282 ++cntIter;
283 return
284 new NullIterator<KV>();
285 }
286
287 public Iterator<KV> iteratorDesc() {
288 return
289 iterator();
290 }
291
292 public Iterator<KV> iteratorBreadthFirst() {
293 return
294 iterator();
295 }
296
297
298 public BinaryTree insert(K k, V v) {
299 return
300 singleton(k, v);
301 }
302
303 public BinaryTree remove(K k) {
304 return
305 this;
306 }
307
308 public BinaryTree
309 unionWith(Function2<V,V,V> op,
310 Map m2) {
311 return
312 (BinaryTree)m2;
313 }
314
315 public BinaryTree
316 differenceWith(Function2<V,V,V> op,
317 Map m2) {
318 return
319 this;
320 }
321
322 public BinaryTree balance() {
323 return
324 this;
325 }
326
327
328
329
330 Empty() { }
331
332 boolean allLS(K k) {
333 return true;
334 }
335 boolean allGT(K k) {
336 return true;
337 }
338
339 Node splitAt(K k) {
340 return
341 new Node(null, null, EMPTY, EMPTY);
342 }
343 }
344
345
346
347
348 private static final
349 class Node
350 extends BinaryTree {
351
352
353 final K k;
354 final V v;
355 final BinaryTree l;
356 final BinaryTree r;
357
358
359
360
361
362
363
364
365 Node(K k, V v, BinaryTree l, BinaryTree r) {
366 assert k != null;
367
368 this.k = k;
369 this.v = v;
370 this.l = l;
371 this.r = r;
372 ++cntNode;
373 }
374
375
376
377
378 public boolean isEmpty() {
379 return false;
380 }
381
382 public int size() {
383 return
384 1 + l.size() + r.size();
385 }
386
387 public int depth() {
388 return
389 1 + max(l.depth(), r.depth());
390 }
391
392 public int minDepth() {
393 return
394 1 + min(l.minDepth(), r.minDepth());
395 }
396
397 public V lookup(K k) {
398 assert k != null;
399
400 switch (signum(k.compareTo(this.k))) {
401 case -1:
402 return
403 l.lookup(k);
404 case 0:
405 return
406 v;
407 case +1:
408 return
409 r.lookup(k);
410 }
411
412 return
413 null;
414 }
415
416 public boolean inv() {
417 return
418 l.allLS(k)
419 &&
420 r.allGT(k)
421 &&
422 l.inv()
423 &&
424 r.inv();
425 }
426
427
428
429 public KV findRoot() {
430 return
431 mkPair(key(), value());
432 }
433
434
435 public KV findMin() {
436 if ( l.isEmpty() )
437 return
438 mkPair(k, v);
439 return
440 l.findMin();
441 }
442
443 public KV findMax() {
444 if ( r.isEmpty() )
445 return
446 mkPair(k, v);
447 return
448 r.findMax();
449 }
450
451 public Iterator<KV> iterator() {
452 return
453 new NodeIterator(this);
454 }
455
456 public Iterator<KV> iteratorDesc() {
457 return
458 new NodeIteratorDescending(this);
459 }
460
461 public Iterator<KV> iteratorBreadthFirst() {
462 return
463 new NodeIteratorBF(this);
464 }
465
466
467
468
469 Node node() { return this; }
470 K key() { return k; }
471 V value() { return v; }
472 BinaryTree left() { return l; }
473 BinaryTree right() { return r; }
474
475
476
477
478 boolean allLS(K k) {
479 return
480 this.k.compareTo(k) < 0
481 &&
482 r.allLS(k)
483
484
485 ;
486 }
487
488 boolean allGT(K k) {
489 return
490 this.k.compareTo(k) > 0
491 &&
492 l.allGT(k)
493
494
495 ;
496 }
497
498
499
500 Node splitAt(K k) {
501 switch ( signum(k.compareTo(this.k)) ) {
502 case -1:
503 Node rl = l.splitAt(k);
504 return
505 rl.setR(this.setL(rl.r));
506 case 0:
507 return
508 this;
509 case +1:
510 Node rr = r.splitAt(k);
511 return
512 rr.setL(this.setR(rr.l));
513 }
514
515 return
516 null;
517 }
518
519
520
521
522 private Node set(K k, V v,
523 BinaryTree l,
524 BinaryTree r) {
525
526 if ( k == this.k && v == this.v
527 &&
528 l == this.l && r == this.r
529 )
530 return
531 this;
532 return
533 new Node(k, v, l, r);
534
535
536
537
538
539
540
541
542
543 }
544 private Node setL(BinaryTree l) {
545
546 if ( l == this.l )
547 return
548 this;
549 return
550 new Node(this.k, this.v, l, this.r);
551
552
553
554
555
556
557 }
558 private Node setR(BinaryTree r) {
559
560 if ( r == this.r )
561 return
562 this;
563 return
564 new Node(this.k, this.v, this.l, r);
565
566
567
568
569
570
571 }
572 private Node setV(V v) {
573
574 return
575 ( v == this.v )
576 ? this
577 : new Node(this.k, v, this.l, this.r);
578
579
580
581
582
583
584 }
585
586
587
588
589 public BinaryTree insert(K k, V v) {
590 assert k != null;
591
592 switch ( signum(k.compareTo(this.k)) ) {
593 case -1:
594 return
595 setL(l.insert(k,v));
596 case 0:
597 return
598 setV(v);
599 case +1:
600 return
601 setR(r.insert(k, v));
602 }
603
604 return
605 null;
606 }
607
608 public BinaryTree remove(K k) {
609 assert k != null;
610
611 switch ( signum(k.compareTo(this.k)) ) {
612 case -1:
613 return
614 setL(l.remove(k));
615 case 0:
616 return
617 removeRoot();
618 case +1:
619 return
620 setR(r.remove(k));
621 }
622
623 return
624 null;
625 }
626
627 private BinaryTree removeRoot() {
628 if ( l.isEmpty() )
629 return
630 r;
631 if ( r.isEmpty() )
632 return
633 l;
634
635
636 KV maxL = l.findMax();
637 BinaryTree newL = l.remove(maxL.fst);
638
639 return
640 set(maxL.fst, maxL.snd, newL, r);
641 }
642
643
644
645 public BinaryTree
646 unionWith(Function2<V,V,V> op,
647 Map m2) {
648 BinaryTree t2 = (BinaryTree)m2;
649 if ( t2.isEmpty() )
650 return
651 this;
652
653 Node splitm2 = t2.splitAt(k);
654 BinaryTree lr = l.unionWith(op, splitm2.l);
655 BinaryTree rr = r.unionWith(op, splitm2.r);
656 V vr = splitm2.k == null ? v : op.apply(v, splitm2.v);
657 return
658 set(k, vr, lr, rr);
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 private static
677 class NodeIterator
678 extends ds.util.Iterator<KV> {
679
680 Queue queue;
681
682 NodeIterator(Node n) {
683 queue = Queue.empty();
684 add(n);
685 ++cntIter;
686 }
687
688 void add(Node n) {
689 queue = queue.cons(n);
690 if ( ! n.l.isEmpty() ) {
691 add(n.l.node());
692 }
693 }
694
695 void addSubNodes(Node n) {
696 if ( ! n.r.isEmpty() )
697 add(n.r.node());
698 }
699
700 public boolean hasNext() {
701 return
702 ! queue.isEmpty();
703 }
704
705 public KV next() {
706 if ( queue.isEmpty() )
707 return
708 undefined("empty tree");
709
710 Node n = (Node)queue.head();
711 queue = queue.tail();
712 addSubNodes(n);
713 return
714 mkPair(n.k, n.v);
715 }
716 }
717
718
719 private
720 class NodeIteratorDescending
721 extends NodeIterator {
722
723 NodeIteratorDescending(Node n) {
724 super(n);
725 }
726
727 void add(Node n) {
728 queue = queue.cons(n);
729 if ( ! n.r.isEmpty() )
730 add(n.r.node());
731 }
732
733 void addSubNodes(Node n) {
734 if ( ! n.l.isEmpty() )
735 add(n.l.node());
736 }
737 }
738
739
740 private
741 class NodeIteratorBF
742 extends NodeIterator {
743
744 NodeIteratorBF(Node n) {
745 super(n);
746 }
747
748 void add(Node n) {
749
750 queue = queue.append(n);
751 }
752
753 void addSubNodes(Node n) {
754 if ( ! n.l.isEmpty() )
755 add(n.l.node());
756 if ( ! n.r.isEmpty() )
757 add(n.r.node());
758 }
759 }
760 }
761
762
763
764
765 private static int cntNode = 0;
766 private static int cntIter = 0;
767
768 public static String stats() {
769 return
770 "stats for ds.persistent.map.BinaryTree:\n" +
771 "# new Node() : " + cntNode + "\n" +
772 "# new Iterator() : " + cntIter + "\n";
773 }
774
775 public String objStats() {
776 int s = size();
777 int o = s;
778 int f = 4 * s;
779 int m = o + f;
780
781 return
782 "mem stats for ds.persistent.map.BinaryTree object:\n" +
783 "# elements (size) : " + s + "\n" +
784 "# objects : " + o + "\n" +
785 "# fields : " + f + "\n" +
786 "# mem words : " + m + "\n";
787 }
788}