Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: packages/quiver/lib/src/collection/treeset.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 Google Inc. All Rights Reserved. 1 // Copyright 2014 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 part of quiver.collection; 15 part of quiver.collection;
16 16
17 /** 17 /// A [Set] of items stored in a binary tree according to [comparator].
18 * A [Set] of items stored in a binary tree according to [comparator]. 18 /// Supports bidirectional iteration.
19 * Supports bidirectional iteration.
20 */
21 abstract class TreeSet<V> extends IterableBase<V> implements Set<V> { 19 abstract class TreeSet<V> extends IterableBase<V> implements Set<V> {
22 final Comparator<V> comparator; 20 final Comparator<V> comparator;
23 21
24 int get length; 22 int get length;
25 23
26 /** 24 /// Create a new [TreeSet] with an ordering defined by [comparator] or the
27 * Create a new [TreeSet] with an ordering defined by [comparator] or the 25 /// default `(a, b) => a.compareTo(b)`.
28 * default `(a, b) => a.compareTo(b)`.
29 */
30 factory TreeSet({Comparator<V> comparator}) { 26 factory TreeSet({Comparator<V> comparator}) {
31 if (comparator == null) { 27 comparator ??= (a, b) => (a as dynamic).compareTo(b);
32 comparator = (a, b) => a.compareTo(b);
33 }
34 return new AvlTreeSet(comparator: comparator); 28 return new AvlTreeSet(comparator: comparator);
35 } 29 }
36 30
37 TreeSet._(this.comparator); 31 TreeSet._(this.comparator);
38 32
39 /** 33 /// Returns an [BidirectionalIterator] that iterates over this tree.
40 * Returns an [BidirectionalIterator] that iterates over this tree.
41 */
42 BidirectionalIterator<V> get iterator; 34 BidirectionalIterator<V> get iterator;
43 35
44 /** 36 /// Returns an [BidirectionalIterator] that iterates over this tree, in
45 * Returns an [BidirectionalIterator] that iterates over this tree, in reverse . 37 /// reverse.
46 */
47 BidirectionalIterator<V> get reverseIterator; 38 BidirectionalIterator<V> get reverseIterator;
48 39
49 /** 40 /// Returns an [BidirectionalIterator] that starts at [anchor]. By default,
50 * Returns an [BidirectionalIterator] that starts at [anchor]. 41 /// the iterator includes the anchor with the first movement; set [inclusive]
51 * By default, the iterator includes the anchor with the first movement; 42 /// to false if you want to exclude the anchor. Set [reversed] to true to
52 * set [inclusive] to false if you want to exclude the anchor. Set [reversed] 43 /// change the direction of of moveNext and movePrevious.
53 * to true to change the direction of of moveNext and movePrevious. 44 ///
54 * 45 /// Note: This iterator allows you to walk the entire set. It does not
55 * Note: This iterator allows you to walk the entire set. It does not present 46 /// present a subview.
56 * a subview.
57 */
58 BidirectionalIterator<V> fromIterator(V anchor, 47 BidirectionalIterator<V> fromIterator(V anchor,
59 {bool reversed: false, bool inclusive: true}); 48 {bool reversed: false, bool inclusive: true});
60 49
61 /** 50 /// Search the tree for the matching [object] or the [nearestOption]
62 * Search the tree for the matching [object] or the [nearestOption] 51 /// if missing. See [TreeSearch].
63 * if missing. See [TreeSearch].
64 */
65 V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST}); 52 V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST});
66 53
67 // TODO: toString or not toString, that is the question. 54 // TODO: toString or not toString, that is the question.
68 } 55 }
69 56
70 /** 57 /// Controls the results for [TreeSet.searchNearest]()
71 * Controls the results for [TreeSet.searchNearest]() 58 enum TreeSearch {
72 */ 59 /// If result not found, always chose the smaller element
73 class TreeSearch { 60 LESS_THAN,
74 61
75 /** 62 /// If result not found, chose the nearest based on comparison
76 * If result not found, always chose the smaler element 63 NEAREST,
77 */
78 static const LESS_THAN = const TreeSearch._(1);
79 64
80 /** 65 /// If result not found, always chose the greater element
81 * If result not found, chose the nearest based on comparison 66 GREATER_THAN
82 */
83 static const NEAREST = const TreeSearch._(2);
84
85 /**
86 * If result not found, always chose the greater element
87 */
88 static const GREATER_THAN = const TreeSearch._(3);
89
90 final int _val;
91 const TreeSearch._(this._val);
92 } 67 }
93 68
94 /** 69 /// A node in the [TreeSet].
95 * A node in the [TreeSet].
96 */
97 abstract class _TreeNode<V> { 70 abstract class _TreeNode<V> {
98 _TreeNode<V> get left; 71 _TreeNode<V> get left;
99 _TreeNode<V> get right; 72 _TreeNode<V> get right;
100 73
101 //TODO(codefu): Remove need for [parent]; this is just an implementation note 74 //TODO(codefu): Remove need for [parent]; this is just an implementation note
102 _TreeNode<V> get parent; 75 _TreeNode<V> get parent;
103 V object; 76 V object;
104 77
105 /** 78 /// TreeNodes are always allocated as leafs.
106 * TreeNodes are always allocated as leafs.
107 */
108 _TreeNode({this.object}); 79 _TreeNode({this.object});
109 80
110 /** 81 /// Return the minimum node for the subtree
111 * Return the minimum node for the subtree
112 */
113 _TreeNode<V> get minimumNode { 82 _TreeNode<V> get minimumNode {
114 var node = this; 83 var node = this;
115 while (node.left != null) { 84 while (node.left != null) {
116 node = node.left; 85 node = node.left;
117 } 86 }
118 return node; 87 return node;
119 } 88 }
120 89
121 /** 90 /// Return the maximum node for the subtree
122 * Return the maximum node for the subtree
123 */
124 _TreeNode<V> get maximumNode { 91 _TreeNode<V> get maximumNode {
125 var node = this; 92 var node = this;
126 while (node.right != null) { 93 while (node.right != null) {
127 node = node.right; 94 node = node.right;
128 } 95 }
129 return node; 96 return node;
130 } 97 }
131 98
132 /** 99 /// Return the next greatest element (or null)
133 * Return the next greatest element (or null)
134 */
135 _TreeNode<V> get successor { 100 _TreeNode<V> get successor {
136 var node = this; 101 var node = this;
137 if (node.right != null) { 102 if (node.right != null) {
138 return node.right.minimumNode; 103 return node.right.minimumNode;
139 } 104 }
140 while (node.parent != null && node == node.parent.right) { 105 while (node.parent != null && node == node.parent.right) {
141 node = node.parent; 106 node = node.parent;
142 } 107 }
143 return node.parent; 108 return node.parent;
144 } 109 }
145 110
146 /** 111 /// Return the next smaller element (or null)
147 * Return the next smaller element (or null)
148 */
149 _TreeNode<V> get predecessor { 112 _TreeNode<V> get predecessor {
150 var node = this; 113 var node = this;
151 if (node.left != null) { 114 if (node.left != null) {
152 return node.left.maximumNode; 115 return node.left.maximumNode;
153 } 116 }
154 while (node.parent != null && node.parent._left == node) { 117 while (node.parent != null && node.parent.left == node) {
155 node = node.parent; 118 node = node.parent;
156 } 119 }
157 return node.parent; 120 return node.parent;
158 } 121 }
159 } 122 }
160 123
161 /** 124 /// AVL implementation of a self-balancing binary tree. Optimized for lookup
162 * AVL implementation of a self-balancing binary tree. Optimized for lookup 125 /// operations.
163 * operations. 126 ///
164 * 127 /// Notes: Adapted from "Introduction to Algorithms", second edition,
165 * Notes: Adapted from "Introduction to Algorithms", second edition, 128 /// by Thomas H. Cormen, Charles E. Leiserson,
166 * by Thomas H. Cormen, Charles E. Leiserson, 129 /// Ronald L. Rivest, Clifford Stein.
167 * Ronald L. Rivest, Clifford Stein. 130 /// chapter 13.2
168 * chapter 13.2
169 */
170 class AvlTreeSet<V> extends TreeSet<V> { 131 class AvlTreeSet<V> extends TreeSet<V> {
171 int _length = 0; 132 int _length = 0;
172 AvlNode<V> _root; 133 AvlNode<V> _root;
173 // Modification count to the tree, monotonically increasing 134 // Modification count to the tree, monotonically increasing
174 int _modCount = 0; 135 int _modCount = 0;
175 136
176 int get length => _length; 137 int get length => _length;
177 138
178 AvlTreeSet({Comparator<V> comparator}) : super._(comparator); 139 AvlTreeSet({Comparator<V> comparator}) : super._(comparator);
179 140
180 /** 141 /// Add the element to the tree.
181 * Add the element to the tree.
182 */
183 bool add(V element) { 142 bool add(V element) {
184 if (_root == null) { 143 if (_root == null) {
185 AvlNode<V> node = new AvlNode<V>(object: element); 144 AvlNode<V> node = new AvlNode<V>(object: element);
186 _root = node; 145 _root = node;
187 ++_length; 146 ++_length;
188 ++_modCount; 147 ++_modCount;
189 return true; 148 return true;
190 } 149 }
191 150
192 AvlNode<V> x = _root; 151 AvlNode<V> x = _root;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 } 242 }
284 node._balanceFactor = 0; 243 node._balanceFactor = 0;
285 } 244 }
286 break; // out of loop, we're balanced 245 break; // out of loop, we're balanced
287 } 246 }
288 } // end of while (balancing) 247 } // end of while (balancing)
289 _length++; 248 _length++;
290 return true; 249 return true;
291 } 250 }
292 251
293 /** 252 /// Test to see if an element is stored in the tree
294 * Test to see if an element is stored in the tree
295 */
296 AvlNode<V> _getNode(V element) { 253 AvlNode<V> _getNode(V element) {
297 if (element == null) return null; 254 if (element == null) return null;
298 AvlNode<V> x = _root; 255 AvlNode<V> x = _root;
299 while (x != null) { 256 while (x != null) {
300 int compare = comparator(element, x.object); 257 int compare = comparator(element, x.object);
301 if (compare == 0) { 258 if (compare == 0) {
302 // This only means our node matches; we need to search for the exact 259 // This only means our node matches; we need to search for the exact
303 // element. We could have been glutons and used a hashmap to back. 260 // element. We could have been glutons and used a hashmap to back.
304 return x; 261 return x;
305 } else if (compare < 0) { 262 } else if (compare < 0) {
306 x = x.left; 263 x = x.left;
307 } else { 264 } else {
308 x = x.right; 265 x = x.right;
309 } 266 }
310 } 267 }
311 return null; 268 return null;
312 } 269 }
313 270
314 /** 271 /// This function will right rotate/pivot N with its left child, placing
315 * This function will right rotate/pivot N with its left child, placing 272 /// it on the right of its left child.
316 * it on the right of its left child. 273 ///
317 * 274 /// N Y
318 * N Y 275 /// / \ / \
319 * / \ / \ 276 /// Y A Z N
320 * Y A Z N 277 /// / \ ==> / \ / \
321 * / \ ==> / \ / \ 278 /// Z B D CB A
322 * Z B D CB A 279 /// / \
323 * / \ 280 /// D C
324 *D C 281 ///
325 * 282 /// Assertion: must have a left element
326 * Assertion: must have a left element
327 */
328 void _rotateRight(AvlNode<V> node) { 283 void _rotateRight(AvlNode<V> node) {
329 AvlNode<V> y = node.left; 284 AvlNode<V> y = node.left;
330 if (y == null) throw new AssertionError(); 285 if (y == null) throw new AssertionError();
331 286
332 // turn Y's right subtree(B) into N's left subtree. 287 // turn Y's right subtree(B) into N's left subtree.
333 node._left = y.right; 288 node._left = y.right;
334 if (node.left != null) { 289 if (node.left != null) {
335 node.left._parent = node; 290 node.left._parent = node;
336 } 291 }
337 y._parent = node.parent; 292 y._parent = node.parent;
338 if (y._parent == null) { 293 if (y._parent == null) {
339 _root = y; 294 _root = y;
340 } else { 295 } else {
341 if (node.parent._left == node) { 296 if (node.parent._left == node) {
342 node.parent._left = y; 297 node.parent._left = y;
343 } else { 298 } else {
344 node.parent._right = y; 299 node.parent._right = y;
345 } 300 }
346 } 301 }
347 y._right = node; 302 y._right = node;
348 node._parent = y; 303 node._parent = y;
349 } 304 }
350 305
351 /** 306 /// This function will left rotate/pivot N with its right child, placing
352 * This function will left rotate/pivot N with its right child, placing 307 /// it on the left of its right child.
353 * it on the left of its right child. 308 ///
354 * 309 /// N Y
355 * N Y 310 /// / \ / \
356 * / \ / \ 311 /// A Y N Z
357 * A Y N Z 312 /// / \ ==> / \ / \
358 * / \ ==> / \ / \ 313 /// B Z A BC D
359 * B Z A BC D 314 /// / \
360 * / \ 315 /// C D
361 * C D 316 ///
362 * 317 /// Assertion: must have a right element
363 * Assertion: must have a right element
364 */
365 void _rotateLeft(AvlNode<V> node) { 318 void _rotateLeft(AvlNode<V> node) {
366 AvlNode<V> y = node.right; 319 AvlNode<V> y = node.right;
367 if (y == null) throw new AssertionError(); 320 if (y == null) throw new AssertionError();
368 321
369 // turn Y's left subtree(B) into N's right subtree. 322 // turn Y's left subtree(B) into N's right subtree.
370 node._right = y.left; 323 node._right = y.left;
371 if (node.right != null) { 324 if (node.right != null) {
372 node.right._parent = node; 325 node.right._parent = node;
373 } 326 }
374 y._parent = node.parent; 327 y._parent = node.parent;
375 if (y._parent == null) { 328 if (y._parent == null) {
376 _root = y; 329 _root = y;
377 } else { 330 } else {
378 if (node.parent._left == node) { 331 if (node.parent._left == node) {
379 y.parent._left = y; 332 y.parent._left = y;
380 } else { 333 } else {
381 y.parent._right = y; 334 y.parent._right = y;
382 } 335 }
383 } 336 }
384 y._left = node; 337 y._left = node;
385 node._parent = y; 338 node._parent = y;
386 } 339 }
387 340
388 /** 341 /// This function will double rotate node with right/left operations.
389 * This function will double rotate node with right/left operations. 342 /// node is S.
390 * node is S. 343 ///
391 * 344 /// S G
392 * S G 345 /// / \ / \
393 * / \ / \ 346 /// A C S C
394 * A C S C 347 /// / \ ==> / \ / \
395 * / \ ==> / \ / \ 348 /// G B A DC B
396 * G B A DC B 349 /// / \
397 * / \ 350 /// D C
398 * D C
399 */
400 void _rotateRightLeft(AvlNode<V> node) { 351 void _rotateRightLeft(AvlNode<V> node) {
401 _rotateRight(node.right); 352 _rotateRight(node.right);
402 _rotateLeft(node); 353 _rotateLeft(node);
403 } 354 }
404 355
405 /** 356 /// This function will double rotate node with left/right operations.
406 * This function will double rotate node with left/right operations. 357 /// node is S.
407 * node is S. 358 ///
408 * 359 /// S G
409 * S G 360 /// / \ / \
410 * / \ / \ 361 /// C A C S
411 * C A C S 362 /// / \ ==> / \ / \
412 * / \ ==> / \ / \ 363 /// B G B CD A
413 *B G B CD A 364 /// / \
414 * / \ 365 /// C D
415 * C D
416 */
417 void _rotateLeftRight(AvlNode<V> node) { 366 void _rotateLeftRight(AvlNode<V> node) {
418 _rotateLeft(node.left); 367 _rotateLeft(node.left);
419 _rotateRight(node); 368 _rotateRight(node);
420 } 369 }
421 370
422 bool addAll(Iterable<V> items) { 371 bool addAll(Iterable<V> items) {
423 bool modified = false; 372 bool modified = false;
424 for (V ele in items) { 373 for (V ele in items) {
425 modified = add(ele) ? true : modified; 374 modified = add(ele) ? true : modified;
426 } 375 }
427 return modified; 376 return modified;
428 } 377 }
429 378
430 void clear() { 379 void clear() {
431 _length = 0; 380 _length = 0;
432 _root = null; 381 _root = null;
433 ++_modCount; 382 ++_modCount;
434 } 383 }
435 384
436 bool containsAll(Iterable<Object> items) { 385 bool containsAll(Iterable<Object> items) {
437 for (var ele in items) { 386 for (var ele in items) {
438 if (!contains(ele)) return false; 387 if (!contains(ele)) return false;
439 } 388 }
440 return true; 389 return true;
441 } 390 }
442 391
443 bool remove(Object item) { 392 bool remove(Object item) {
444 AvlNode<V> x = _getNode(item); 393 if (item is! V) return false;
394
395 AvlNode<V> x = _getNode(item as V);
445 if (x != null) { 396 if (x != null) {
446 _removeNode(x); 397 _removeNode(x);
447 return true; 398 return true;
448 } 399 }
449 return false; 400 return false;
450 } 401 }
451 402
452 void _removeNode(AvlNode<V> node) { 403 void _removeNode(AvlNode<V> node) {
453 AvlNode<V> y, w; 404 AvlNode<V> y, w;
454 405
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 if (node.parent.left == node) { 561 if (node.parent.left == node) {
611 node.parent._balanceFactor += 1; 562 node.parent._balanceFactor += 1;
612 } else { 563 } else {
613 node.parent._balanceFactor -= 1; 564 node.parent._balanceFactor -= 1;
614 } 565 }
615 } 566 }
616 node = node.parent; 567 node = node.parent;
617 } 568 }
618 } 569 }
619 570
620 /** 571 /// See [Set.removeAll]
621 * See [Set.removeAll]
622 */
623 void removeAll(Iterable items) { 572 void removeAll(Iterable items) {
624 for (var ele in items) { 573 for (var ele in items) {
625 remove(ele); 574 remove(ele);
626 } 575 }
627 } 576 }
628 577
629 /** 578 /// See [Set.retainAll]
630 * See [Set.retainAll]
631 */
632 void retainAll(Iterable<Object> elements) { 579 void retainAll(Iterable<Object> elements) {
633 List<V> chosen = []; 580 List<V> chosen = <V>[];
634 for (var target in elements) { 581 for (var target in elements) {
635 if (contains(target)) { 582 if (target is V && contains(target)) {
636 chosen.add(target); 583 chosen.add(target);
637 } 584 }
638 } 585 }
639 clear(); 586 clear();
640 addAll(chosen); 587 addAll(chosen);
641 } 588 }
642 589
643 /** 590 /// See [Set.retainWhere]
644 * See [Set.retainWhere]
645 */
646 void retainWhere(bool test(V element)) { 591 void retainWhere(bool test(V element)) {
647 List<V> chosen = []; 592 List<V> chosen = [];
648 for (var target in this) { 593 for (var target in this) {
649 if (test(target)) { 594 if (test(target)) {
650 chosen.add(target); 595 chosen.add(target);
651 } 596 }
652 } 597 }
653 clear(); 598 clear();
654 addAll(chosen); 599 addAll(chosen);
655 } 600 }
656 601
657 /** 602 /// See [Set.removeWhere]
658 * See [Set.removeWhere]
659 */
660 void removeWhere(bool test(V element)) { 603 void removeWhere(bool test(V element)) {
661 List<V> damned = []; 604 List<V> damned = [];
662 for (var target in this) { 605 for (var target in this) {
663 if (test(target)) { 606 if (test(target)) {
664 damned.add(target); 607 damned.add(target);
665 } 608 }
666 } 609 }
667 removeAll(damned); 610 removeAll(damned);
668 } 611 }
669 612
670 /** 613 /// See [IterableBase.first]
671 * See [IterableBase.first]
672 */
673 V get first { 614 V get first {
674 if (_root == null) return null; 615 if (_root == null) return null;
675 AvlNode<V> min = _root.minimumNode; 616 AvlNode<V> min = _root.minimumNode;
676 return min != null ? min.object : null; 617 return min != null ? min.object : null;
677 } 618 }
678 619
679 /** 620 /// See [IterableBase.last]
680 * See [IterableBase.last]
681 */
682 V get last { 621 V get last {
683 if (_root == null) return null; 622 if (_root == null) return null;
684 AvlNode<V> max = _root.maximumNode; 623 AvlNode<V> max = _root.maximumNode;
685 return max != null ? max.object : null; 624 return max != null ? max.object : null;
686 } 625 }
687 626
688 /** 627 /// See [Set.lookup]
689 * See [Set.lookup]
690 */
691 V lookup(Object element) { 628 V lookup(Object element) {
692 if (element == null || _root == null) return null; 629 if (element is! V || _root == null) return null;
693 AvlNode<V> x = _root; 630 AvlNode<V> x = _root;
694 int compare = 0; 631 int compare = 0;
695 while (x != null) { 632 while (x != null) {
696 compare = comparator(element, x.object); 633 compare = comparator(element as V, x.object);
697 if (compare == 0) { 634 if (compare == 0) {
698 return x.object; 635 return x.object;
699 } else if (compare < 0) { 636 } else if (compare < 0) {
700 x = x.left; 637 x = x.left;
701 } else { 638 } else {
702 x = x.right; 639 x = x.right;
703 } 640 }
704 } 641 }
705 return null; 642 return null;
706 } 643 }
707 644
708 V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST}) { 645 V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST}) {
709 AvlNode<V> found = _searchNearest(object, option: nearestOption); 646 AvlNode<V> found = _searchNearest(object, option: nearestOption);
710 return (found != null) ? found.object : null; 647 return (found != null) ? found.object : null;
711 } 648 }
712 649
713 /** 650 /// Search the tree for the matching element, or the 'nearest' node.
714 * Search the tree for the matching element, or the 'nearest' node. 651 /// NOTE: [BinaryTree.comparator] needs to have finer granulatity than -1,0,1
715 * NOTE: [BinaryTree.comparator] needs to have finer granulatity than -1,0,1 652 /// in order for this to return something that's meaningful.
716 * in order for this to return something that's meaningful.
717 */
718 AvlNode<V> _searchNearest(V element, 653 AvlNode<V> _searchNearest(V element,
719 {TreeSearch option: TreeSearch.NEAREST}) { 654 {TreeSearch option: TreeSearch.NEAREST}) {
720 if (element == null || _root == null) { 655 if (element == null || _root == null) {
721 return null; 656 return null;
722 } 657 }
723 AvlNode<V> x = _root; 658 AvlNode<V> x = _root;
724 AvlNode<V> previous; 659 AvlNode<V> previous;
725 int compare = 0; 660 int compare = 0;
726 while (x != null) { 661 while (x != null) {
727 previous = x; 662 previous = x;
(...skipping 23 matching lines...) Expand all
751 if (compare < 0) { 686 if (compare < 0) {
752 return compare.abs() < otherCompare ? previous : x; 687 return compare.abs() < otherCompare ? previous : x;
753 } 688 }
754 return otherCompare.abs() < compare ? x : previous; 689 return otherCompare.abs() < compare ? x : previous;
755 } 690 }
756 691
757 // 692 //
758 // [IterableBase]<V> Methods 693 // [IterableBase]<V> Methods
759 // 694 //
760 695
761 /** 696 /// See [IterableBase.iterator]
762 * See [IterableBase.iterator]
763 */
764 BidirectionalIterator<V> get iterator => new _AvlTreeIterator._(this); 697 BidirectionalIterator<V> get iterator => new _AvlTreeIterator._(this);
765 698
766 /** 699 /// See [TreeSet.reverseIterator]
767 * See [TreeSet.reverseIterator]
768 */
769 BidirectionalIterator<V> get reverseIterator => 700 BidirectionalIterator<V> get reverseIterator =>
770 new _AvlTreeIterator._(this, reversed: true); 701 new _AvlTreeIterator._(this, reversed: true);
771 702
772 /** 703 /// See [TreeSet.fromIterator]
773 * See [TreeSet.fromIterator]
774 */
775 BidirectionalIterator<V> fromIterator(V anchor, 704 BidirectionalIterator<V> fromIterator(V anchor,
776 {bool reversed: false, bool inclusive: true}) => 705 {bool reversed: false, bool inclusive: true}) =>
777 new _AvlTreeIterator<V>._(this, 706 new _AvlTreeIterator<V>._(this,
778 anchorObject: anchor, reversed: reversed, inclusive: inclusive); 707 anchorObject: anchor, reversed: reversed, inclusive: inclusive);
779 708
780 /** 709 /// See [IterableBase.contains]
781 * See [IterableBase.contains]
782 */
783 bool contains(Object object) { 710 bool contains(Object object) {
784 AvlNode<V> x = _getNode(object as V); 711 AvlNode<V> x = _getNode(object as V);
785 return x != null; 712 return x != null;
786 } 713 }
787 714
788 // 715 //
789 // [Set] methods 716 // [Set] methods
790 // 717 //
791 718
792 /** 719 /// See [Set.intersection]
793 * See [Set.intersection]
794 */
795 Set<V> intersection(Set<Object> other) { 720 Set<V> intersection(Set<Object> other) {
796 TreeSet<V> set = new TreeSet(comparator: comparator); 721 TreeSet<V> set = new TreeSet(comparator: comparator);
797 722
798 // Opitimized for sorted sets 723 // Optimized for sorted sets
799 if (other is TreeSet) { 724 if (other is TreeSet<V>) {
800 var i1 = iterator; 725 var i1 = iterator;
801 var i2 = other.iterator; 726 var i2 = other.iterator;
802 var hasMore1 = i1.moveNext(); 727 var hasMore1 = i1.moveNext();
803 var hasMore2 = i2.moveNext(); 728 var hasMore2 = i2.moveNext();
804 while (hasMore1 && hasMore2) { 729 while (hasMore1 && hasMore2) {
805 var c = comparator(i1.current, i2.current); 730 var c = comparator(i1.current, i2.current);
806 if (c == 0) { 731 if (c == 0) {
807 set.add(i1.current); 732 set.add(i1.current);
808 hasMore1 = i1.moveNext(); 733 hasMore1 = i1.moveNext();
809 hasMore2 = i2.moveNext(); 734 hasMore2 = i2.moveNext();
810 } else if (c < 0) { 735 } else if (c < 0) {
811 hasMore1 = i1.moveNext(); 736 hasMore1 = i1.moveNext();
812 } else { 737 } else {
813 hasMore2 = i2.moveNext(); 738 hasMore2 = i2.moveNext();
814 } 739 }
815 } 740 }
816 return set; 741 return set;
817 } 742 }
818 743
819 // Non-optimized version. 744 // Non-optimized version.
820 for (var target in this) { 745 for (var target in this) {
821 if (other.contains(target)) { 746 if (other.contains(target)) {
822 set.add(target); 747 set.add(target);
823 } 748 }
824 } 749 }
825 return set; 750 return set;
826 } 751 }
827 752
828 /** 753 /// See [Set.union]
829 * See [Set.union]
830 */
831 Set<V> union(Set<V> other) { 754 Set<V> union(Set<V> other) {
832 TreeSet<V> set = new TreeSet(comparator: comparator); 755 TreeSet<V> set = new TreeSet(comparator: comparator);
833 756
834 if (other is TreeSet) { 757 if (other is TreeSet) {
835 var i1 = iterator; 758 var i1 = iterator;
836 var i2 = other.iterator; 759 var i2 = other.iterator;
837 var hasMore1 = i1.moveNext(); 760 var hasMore1 = i1.moveNext();
838 var hasMore2 = i2.moveNext(); 761 var hasMore2 = i2.moveNext();
839 while (hasMore1 && hasMore2) { 762 while (hasMore1 && hasMore2) {
840 var c = comparator(i1.current, i2.current); 763 var c = comparator(i1.current, i2.current);
(...skipping 12 matching lines...) Expand all
853 if (hasMore1 || hasMore2) { 776 if (hasMore1 || hasMore2) {
854 i1 = hasMore1 ? i1 : i2; 777 i1 = hasMore1 ? i1 : i2;
855 do { 778 do {
856 set.add(i1.current); 779 set.add(i1.current);
857 } while (i1.moveNext()); 780 } while (i1.moveNext());
858 } 781 }
859 return set; 782 return set;
860 } 783 }
861 784
862 // Non-optimized version. 785 // Non-optimized version.
863 return set 786 return set..addAll(this)..addAll(other);
864 ..addAll(this)
865 ..addAll(other);
866 } 787 }
867 788
868 /** 789 /// See [Set.difference]
869 * See [Set.difference] 790 Set<V> difference(Set<Object> other) {
870 */
871 Set<V> difference(Set<V> other) {
872 TreeSet<V> set = new TreeSet(comparator: comparator); 791 TreeSet<V> set = new TreeSet(comparator: comparator);
873 792
874 if (other is TreeSet) { 793 if (other is TreeSet) {
875 var i1 = iterator; 794 var i1 = iterator;
876 var i2 = other.iterator; 795 var i2 = other.iterator;
877 var hasMore1 = i1.moveNext(); 796 var hasMore1 = i1.moveNext();
878 var hasMore2 = i2.moveNext(); 797 var hasMore2 = i2.moveNext();
879 while (hasMore1 && hasMore2) { 798 while (hasMore1 && hasMore2) {
880 var c = comparator(i1.current, i2.current); 799 var c = comparator(i1.current, i2.current);
881 if (c == 0) { 800 if (c == 0) {
(...skipping 16 matching lines...) Expand all
898 817
899 // Non-optimized version. 818 // Non-optimized version.
900 for (var target in this) { 819 for (var target in this) {
901 if (!other.contains(target)) { 820 if (!other.contains(target)) {
902 set.add(target); 821 set.add(target);
903 } 822 }
904 } 823 }
905 return set; 824 return set;
906 } 825 }
907 826
908 /** 827 /// Visible for testing only.
909 * Visible for testing only.
910 */
911 AvlNode<V> getNode(V object) => _getNode(object); 828 AvlNode<V> getNode(V object) => _getNode(object);
912 } 829 }
913 830
914 typedef bool _IteratorMove(); 831 typedef bool _IteratorMove();
915 832
916 /** 833 /// This iterator either starts at the beginning or end (see [TreeSet.iterator]
917 * This iterator either starts at the beginning or end (see [TreeSet.iterator] 834 /// and [TreeSet.reverseIterator]) or from an anchor point in the set (see
918 * and [TreeSet.reverseIterator]) or from an anchor point in the set (see 835 /// [TreeSet.fromIterator]). When using fromIterator, the inital anchor point
919 * [TreeSet.fromIterator]). When using fromIterator, the inital 836 /// is included in the first movement (either [moveNext] or [movePrevious]) but
920 * anchor point is included in the first movement (either [moveNext] or 837 /// can optionally be excluded in the constructor.
921 * [movePrevious]) but can optionally be excluded in the constructor.
922 */
923 class _AvlTreeIterator<V> implements BidirectionalIterator<V> { 838 class _AvlTreeIterator<V> implements BidirectionalIterator<V> {
924 static const LEFT = -1; 839 static const LEFT = -1;
925 static const WALK = 0; 840 static const WALK = 0;
926 static const RIGHT = 1; 841 static const RIGHT = 1;
927 842
928 final bool reversed; 843 final bool reversed;
929 final AvlTreeSet<V> tree; 844 final AvlTreeSet<V> tree;
930 final int _modCountGuard; 845 final int _modCountGuard;
931 final Object anchorObject; 846 final V anchorObject;
932 final bool inclusive; 847 final bool inclusive;
933 848
934 _IteratorMove _moveNext; 849 _IteratorMove _moveNext;
935 _IteratorMove _movePrevious; 850 _IteratorMove _movePrevious;
936 851
937 int state; 852 int state;
938 _TreeNode<V> _current; 853 _TreeNode<V> _current;
939 854
940 _AvlTreeIterator._(AvlTreeSet<V> tree, 855 _AvlTreeIterator._(AvlTreeSet<V> tree,
941 {reversed: false, this.inclusive: true, this.anchorObject: null}) 856 {reversed: false, this.inclusive: true, this.anchorObject: null})
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 default: 936 default:
1022 _current = _current.predecessor; 937 _current = _current.predecessor;
1023 if (_current == null) { 938 if (_current == null) {
1024 state = LEFT; 939 state = LEFT;
1025 } 940 }
1026 return state == WALK; 941 return state == WALK;
1027 } 942 }
1028 } 943 }
1029 } 944 }
1030 945
1031 /** 946 /// Private class used to track element insertions in the [TreeSet].
1032 * Private class used to track element insertions in the [TreeSet].
1033 */
1034 class AvlNode<V> extends _TreeNode<V> { 947 class AvlNode<V> extends _TreeNode<V> {
1035 AvlNode<V> _left; 948 AvlNode<V> _left;
1036 AvlNode<V> _right; 949 AvlNode<V> _right;
1037 //TODO(codefu): Remove need for [parent]; this is just an implementation note 950 // TODO(codefu): Remove need for [parent]; this is just an implementation note
1038 AvlNode<V> _parent; 951 AvlNode<V> _parent;
1039 int _balanceFactor = 0; 952 int _balanceFactor = 0;
1040 953
1041 AvlNode<V> get left => _left; 954 AvlNode<V> get left => _left;
1042 AvlNode<V> get right => _right; 955 AvlNode<V> get right => _right;
1043 AvlNode<V> get parent => _parent; 956 AvlNode<V> get parent => _parent;
1044 int get balance => _balanceFactor; 957 int get balance => _balanceFactor;
1045 958
1046 AvlNode({V object}) : super(object: object); 959 AvlNode({V object}) : super(object: object);
1047 960
1048 String toString() => 961 String toString() =>
1049 "(b:$balance o: $object l:${left != null} r:${right != null})"; 962 "(b:$balance o: $object l:${left != null} r:${right != null})";
1050 } 963 }
OLDNEW
« no previous file with comments | « packages/quiver/lib/src/collection/multimap.dart ('k') | packages/quiver/lib/src/core/hash.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698