Index: packages/quiver/lib/src/collection/treeset.dart |
diff --git a/packages/quiver/lib/src/collection/treeset.dart b/packages/quiver/lib/src/collection/treeset.dart |
index 200c21fcf1a61df65451a798e40cf3d31b6c0cf6..6375a21744584935d95e7e0fd31656c24b20e0b4 100644 |
--- a/packages/quiver/lib/src/collection/treeset.dart |
+++ b/packages/quiver/lib/src/collection/treeset.dart |
@@ -14,86 +14,59 @@ |
part of quiver.collection; |
-/** |
- * A [Set] of items stored in a binary tree according to [comparator]. |
- * Supports bidirectional iteration. |
- */ |
+/// A [Set] of items stored in a binary tree according to [comparator]. |
+/// Supports bidirectional iteration. |
abstract class TreeSet<V> extends IterableBase<V> implements Set<V> { |
final Comparator<V> comparator; |
int get length; |
- /** |
- * Create a new [TreeSet] with an ordering defined by [comparator] or the |
- * default `(a, b) => a.compareTo(b)`. |
- */ |
+ /// Create a new [TreeSet] with an ordering defined by [comparator] or the |
+ /// default `(a, b) => a.compareTo(b)`. |
factory TreeSet({Comparator<V> comparator}) { |
- if (comparator == null) { |
- comparator = (a, b) => a.compareTo(b); |
- } |
+ comparator ??= (a, b) => (a as dynamic).compareTo(b); |
return new AvlTreeSet(comparator: comparator); |
} |
TreeSet._(this.comparator); |
- /** |
- * Returns an [BidirectionalIterator] that iterates over this tree. |
- */ |
+ /// Returns an [BidirectionalIterator] that iterates over this tree. |
BidirectionalIterator<V> get iterator; |
- /** |
- * Returns an [BidirectionalIterator] that iterates over this tree, in reverse. |
- */ |
+ /// Returns an [BidirectionalIterator] that iterates over this tree, in |
+ /// reverse. |
BidirectionalIterator<V> get reverseIterator; |
- /** |
- * Returns an [BidirectionalIterator] that starts at [anchor]. |
- * By default, the iterator includes the anchor with the first movement; |
- * set [inclusive] to false if you want to exclude the anchor. Set [reversed] |
- * to true to change the direction of of moveNext and movePrevious. |
- * |
- * Note: This iterator allows you to walk the entire set. It does not present |
- * a subview. |
- */ |
+ /// Returns an [BidirectionalIterator] that starts at [anchor]. By default, |
+ /// the iterator includes the anchor with the first movement; set [inclusive] |
+ /// to false if you want to exclude the anchor. Set [reversed] to true to |
+ /// change the direction of of moveNext and movePrevious. |
+ /// |
+ /// Note: This iterator allows you to walk the entire set. It does not |
+ /// present a subview. |
BidirectionalIterator<V> fromIterator(V anchor, |
{bool reversed: false, bool inclusive: true}); |
- /** |
- * Search the tree for the matching [object] or the [nearestOption] |
- * if missing. See [TreeSearch]. |
- */ |
+ /// Search the tree for the matching [object] or the [nearestOption] |
+ /// if missing. See [TreeSearch]. |
V nearest(V object, {TreeSearch nearestOption: TreeSearch.NEAREST}); |
// TODO: toString or not toString, that is the question. |
} |
-/** |
- * Controls the results for [TreeSet.searchNearest]() |
- */ |
-class TreeSearch { |
- |
- /** |
- * If result not found, always chose the smaler element |
- */ |
- static const LESS_THAN = const TreeSearch._(1); |
+/// Controls the results for [TreeSet.searchNearest]() |
+enum TreeSearch { |
+ /// If result not found, always chose the smaller element |
+ LESS_THAN, |
- /** |
- * If result not found, chose the nearest based on comparison |
- */ |
- static const NEAREST = const TreeSearch._(2); |
+ /// If result not found, chose the nearest based on comparison |
+ NEAREST, |
- /** |
- * If result not found, always chose the greater element |
- */ |
- static const GREATER_THAN = const TreeSearch._(3); |
- |
- final int _val; |
- const TreeSearch._(this._val); |
+ /// If result not found, always chose the greater element |
+ GREATER_THAN |
} |
-/** |
- * A node in the [TreeSet]. |
- */ |
+/// A node in the [TreeSet]. |
abstract class _TreeNode<V> { |
_TreeNode<V> get left; |
_TreeNode<V> get right; |
@@ -102,14 +75,10 @@ abstract class _TreeNode<V> { |
_TreeNode<V> get parent; |
V object; |
- /** |
- * TreeNodes are always allocated as leafs. |
- */ |
+ /// TreeNodes are always allocated as leafs. |
_TreeNode({this.object}); |
- /** |
- * Return the minimum node for the subtree |
- */ |
+ /// Return the minimum node for the subtree |
_TreeNode<V> get minimumNode { |
var node = this; |
while (node.left != null) { |
@@ -118,9 +87,7 @@ abstract class _TreeNode<V> { |
return node; |
} |
- /** |
- * Return the maximum node for the subtree |
- */ |
+ /// Return the maximum node for the subtree |
_TreeNode<V> get maximumNode { |
var node = this; |
while (node.right != null) { |
@@ -129,9 +96,7 @@ abstract class _TreeNode<V> { |
return node; |
} |
- /** |
- * Return the next greatest element (or null) |
- */ |
+ /// Return the next greatest element (or null) |
_TreeNode<V> get successor { |
var node = this; |
if (node.right != null) { |
@@ -143,30 +108,26 @@ abstract class _TreeNode<V> { |
return node.parent; |
} |
- /** |
- * Return the next smaller element (or null) |
- */ |
+ /// Return the next smaller element (or null) |
_TreeNode<V> get predecessor { |
var node = this; |
if (node.left != null) { |
return node.left.maximumNode; |
} |
- while (node.parent != null && node.parent._left == node) { |
+ while (node.parent != null && node.parent.left == node) { |
node = node.parent; |
} |
return node.parent; |
} |
} |
-/** |
- * AVL implementation of a self-balancing binary tree. Optimized for lookup |
- * operations. |
- * |
- * Notes: Adapted from "Introduction to Algorithms", second edition, |
- * by Thomas H. Cormen, Charles E. Leiserson, |
- * Ronald L. Rivest, Clifford Stein. |
- * chapter 13.2 |
- */ |
+/// AVL implementation of a self-balancing binary tree. Optimized for lookup |
+/// operations. |
+/// |
+/// Notes: Adapted from "Introduction to Algorithms", second edition, |
+/// by Thomas H. Cormen, Charles E. Leiserson, |
+/// Ronald L. Rivest, Clifford Stein. |
+/// chapter 13.2 |
class AvlTreeSet<V> extends TreeSet<V> { |
int _length = 0; |
AvlNode<V> _root; |
@@ -177,9 +138,7 @@ class AvlTreeSet<V> extends TreeSet<V> { |
AvlTreeSet({Comparator<V> comparator}) : super._(comparator); |
- /** |
- * Add the element to the tree. |
- */ |
+ /// Add the element to the tree. |
bool add(V element) { |
if (_root == null) { |
AvlNode<V> node = new AvlNode<V>(object: element); |
@@ -290,9 +249,7 @@ class AvlTreeSet<V> extends TreeSet<V> { |
return true; |
} |
- /** |
- * Test to see if an element is stored in the tree |
- */ |
+ /// Test to see if an element is stored in the tree |
AvlNode<V> _getNode(V element) { |
if (element == null) return null; |
AvlNode<V> x = _root; |
@@ -311,20 +268,18 @@ class AvlTreeSet<V> extends TreeSet<V> { |
return null; |
} |
- /** |
- * This function will right rotate/pivot N with its left child, placing |
- * it on the right of its left child. |
- * |
- * N Y |
- * / \ / \ |
- * Y A Z N |
- * / \ ==> / \ / \ |
- * Z B D CB A |
- * / \ |
- *D C |
- * |
- * Assertion: must have a left element |
- */ |
+ /// This function will right rotate/pivot N with its left child, placing |
+ /// it on the right of its left child. |
+ /// |
+ /// N Y |
+ /// / \ / \ |
+ /// Y A Z N |
+ /// / \ ==> / \ / \ |
+ /// Z B D CB A |
+ /// / \ |
+ /// D C |
+ /// |
+ /// Assertion: must have a left element |
void _rotateRight(AvlNode<V> node) { |
AvlNode<V> y = node.left; |
if (y == null) throw new AssertionError(); |
@@ -348,20 +303,18 @@ class AvlTreeSet<V> extends TreeSet<V> { |
node._parent = y; |
} |
- /** |
- * This function will left rotate/pivot N with its right child, placing |
- * it on the left of its right child. |
- * |
- * N Y |
- * / \ / \ |
- * A Y N Z |
- * / \ ==> / \ / \ |
- * B Z A BC D |
- * / \ |
- * C D |
- * |
- * Assertion: must have a right element |
- */ |
+ /// This function will left rotate/pivot N with its right child, placing |
+ /// it on the left of its right child. |
+ /// |
+ /// N Y |
+ /// / \ / \ |
+ /// A Y N Z |
+ /// / \ ==> / \ / \ |
+ /// B Z A BC D |
+ /// / \ |
+ /// C D |
+ /// |
+ /// Assertion: must have a right element |
void _rotateLeft(AvlNode<V> node) { |
AvlNode<V> y = node.right; |
if (y == null) throw new AssertionError(); |
@@ -385,35 +338,31 @@ class AvlTreeSet<V> extends TreeSet<V> { |
node._parent = y; |
} |
- /** |
- * This function will double rotate node with right/left operations. |
- * node is S. |
- * |
- * S G |
- * / \ / \ |
- * A C S C |
- * / \ ==> / \ / \ |
- * G B A DC B |
- * / \ |
- * D C |
- */ |
+ /// This function will double rotate node with right/left operations. |
+ /// node is S. |
+ /// |
+ /// S G |
+ /// / \ / \ |
+ /// A C S C |
+ /// / \ ==> / \ / \ |
+ /// G B A DC B |
+ /// / \ |
+ /// D C |
void _rotateRightLeft(AvlNode<V> node) { |
_rotateRight(node.right); |
_rotateLeft(node); |
} |
- /** |
- * This function will double rotate node with left/right operations. |
- * node is S. |
- * |
- * S G |
- * / \ / \ |
- * C A C S |
- * / \ ==> / \ / \ |
- *B G B CD A |
- * / \ |
- * C D |
- */ |
+ /// This function will double rotate node with left/right operations. |
+ /// node is S. |
+ /// |
+ /// S G |
+ /// / \ / \ |
+ /// C A C S |
+ /// / \ ==> / \ / \ |
+ /// B G B CD A |
+ /// / \ |
+ /// C D |
void _rotateLeftRight(AvlNode<V> node) { |
_rotateLeft(node.left); |
_rotateRight(node); |
@@ -441,7 +390,9 @@ class AvlTreeSet<V> extends TreeSet<V> { |
} |
bool remove(Object item) { |
- AvlNode<V> x = _getNode(item); |
+ if (item is! V) return false; |
+ |
+ AvlNode<V> x = _getNode(item as V); |
if (x != null) { |
_removeNode(x); |
return true; |
@@ -617,22 +568,18 @@ class AvlTreeSet<V> extends TreeSet<V> { |
} |
} |
- /** |
- * See [Set.removeAll] |
- */ |
+ /// See [Set.removeAll] |
void removeAll(Iterable items) { |
for (var ele in items) { |
remove(ele); |
} |
} |
- /** |
- * See [Set.retainAll] |
- */ |
+ /// See [Set.retainAll] |
void retainAll(Iterable<Object> elements) { |
- List<V> chosen = []; |
+ List<V> chosen = <V>[]; |
for (var target in elements) { |
- if (contains(target)) { |
+ if (target is V && contains(target)) { |
chosen.add(target); |
} |
} |
@@ -640,9 +587,7 @@ class AvlTreeSet<V> extends TreeSet<V> { |
addAll(chosen); |
} |
- /** |
- * See [Set.retainWhere] |
- */ |
+ /// See [Set.retainWhere] |
void retainWhere(bool test(V element)) { |
List<V> chosen = []; |
for (var target in this) { |
@@ -654,9 +599,7 @@ class AvlTreeSet<V> extends TreeSet<V> { |
addAll(chosen); |
} |
- /** |
- * See [Set.removeWhere] |
- */ |
+ /// See [Set.removeWhere] |
void removeWhere(bool test(V element)) { |
List<V> damned = []; |
for (var target in this) { |
@@ -667,33 +610,27 @@ class AvlTreeSet<V> extends TreeSet<V> { |
removeAll(damned); |
} |
- /** |
- * See [IterableBase.first] |
- */ |
+ /// See [IterableBase.first] |
V get first { |
if (_root == null) return null; |
AvlNode<V> min = _root.minimumNode; |
return min != null ? min.object : null; |
} |
- /** |
- * See [IterableBase.last] |
- */ |
+ /// See [IterableBase.last] |
V get last { |
if (_root == null) return null; |
AvlNode<V> max = _root.maximumNode; |
return max != null ? max.object : null; |
} |
- /** |
- * See [Set.lookup] |
- */ |
+ /// See [Set.lookup] |
V lookup(Object element) { |
- if (element == null || _root == null) return null; |
+ if (element is! V || _root == null) return null; |
AvlNode<V> x = _root; |
int compare = 0; |
while (x != null) { |
- compare = comparator(element, x.object); |
+ compare = comparator(element as V, x.object); |
if (compare == 0) { |
return x.object; |
} else if (compare < 0) { |
@@ -710,11 +647,9 @@ class AvlTreeSet<V> extends TreeSet<V> { |
return (found != null) ? found.object : null; |
} |
- /** |
- * Search the tree for the matching element, or the 'nearest' node. |
- * NOTE: [BinaryTree.comparator] needs to have finer granulatity than -1,0,1 |
- * in order for this to return something that's meaningful. |
- */ |
+ /// Search the tree for the matching element, or the 'nearest' node. |
+ /// NOTE: [BinaryTree.comparator] needs to have finer granulatity than -1,0,1 |
+ /// in order for this to return something that's meaningful. |
AvlNode<V> _searchNearest(V element, |
{TreeSearch option: TreeSearch.NEAREST}) { |
if (element == null || _root == null) { |
@@ -758,28 +693,20 @@ class AvlTreeSet<V> extends TreeSet<V> { |
// [IterableBase]<V> Methods |
// |
- /** |
- * See [IterableBase.iterator] |
- */ |
+ /// See [IterableBase.iterator] |
BidirectionalIterator<V> get iterator => new _AvlTreeIterator._(this); |
- /** |
- * See [TreeSet.reverseIterator] |
- */ |
+ /// See [TreeSet.reverseIterator] |
BidirectionalIterator<V> get reverseIterator => |
new _AvlTreeIterator._(this, reversed: true); |
- /** |
- * See [TreeSet.fromIterator] |
- */ |
+ /// See [TreeSet.fromIterator] |
BidirectionalIterator<V> fromIterator(V anchor, |
{bool reversed: false, bool inclusive: true}) => |
new _AvlTreeIterator<V>._(this, |
anchorObject: anchor, reversed: reversed, inclusive: inclusive); |
- /** |
- * See [IterableBase.contains] |
- */ |
+ /// See [IterableBase.contains] |
bool contains(Object object) { |
AvlNode<V> x = _getNode(object as V); |
return x != null; |
@@ -789,14 +716,12 @@ class AvlTreeSet<V> extends TreeSet<V> { |
// [Set] methods |
// |
- /** |
- * See [Set.intersection] |
- */ |
+ /// See [Set.intersection] |
Set<V> intersection(Set<Object> other) { |
TreeSet<V> set = new TreeSet(comparator: comparator); |
- // Opitimized for sorted sets |
- if (other is TreeSet) { |
+ // Optimized for sorted sets |
+ if (other is TreeSet<V>) { |
var i1 = iterator; |
var i2 = other.iterator; |
var hasMore1 = i1.moveNext(); |
@@ -825,9 +750,7 @@ class AvlTreeSet<V> extends TreeSet<V> { |
return set; |
} |
- /** |
- * See [Set.union] |
- */ |
+ /// See [Set.union] |
Set<V> union(Set<V> other) { |
TreeSet<V> set = new TreeSet(comparator: comparator); |
@@ -860,15 +783,11 @@ class AvlTreeSet<V> extends TreeSet<V> { |
} |
// Non-optimized version. |
- return set |
- ..addAll(this) |
- ..addAll(other); |
+ return set..addAll(this)..addAll(other); |
} |
- /** |
- * See [Set.difference] |
- */ |
- Set<V> difference(Set<V> other) { |
+ /// See [Set.difference] |
+ Set<V> difference(Set<Object> other) { |
TreeSet<V> set = new TreeSet(comparator: comparator); |
if (other is TreeSet) { |
@@ -905,21 +824,17 @@ class AvlTreeSet<V> extends TreeSet<V> { |
return set; |
} |
- /** |
- * Visible for testing only. |
- */ |
+ /// Visible for testing only. |
AvlNode<V> getNode(V object) => _getNode(object); |
} |
typedef bool _IteratorMove(); |
-/** |
- * This iterator either starts at the beginning or end (see [TreeSet.iterator] |
- * and [TreeSet.reverseIterator]) or from an anchor point in the set (see |
- * [TreeSet.fromIterator]). When using fromIterator, the inital |
- * anchor point is included in the first movement (either [moveNext] or |
- * [movePrevious]) but can optionally be excluded in the constructor. |
- */ |
+/// This iterator either starts at the beginning or end (see [TreeSet.iterator] |
+/// and [TreeSet.reverseIterator]) or from an anchor point in the set (see |
+/// [TreeSet.fromIterator]). When using fromIterator, the inital anchor point |
+/// is included in the first movement (either [moveNext] or [movePrevious]) but |
+/// can optionally be excluded in the constructor. |
class _AvlTreeIterator<V> implements BidirectionalIterator<V> { |
static const LEFT = -1; |
static const WALK = 0; |
@@ -928,7 +843,7 @@ class _AvlTreeIterator<V> implements BidirectionalIterator<V> { |
final bool reversed; |
final AvlTreeSet<V> tree; |
final int _modCountGuard; |
- final Object anchorObject; |
+ final V anchorObject; |
final bool inclusive; |
_IteratorMove _moveNext; |
@@ -1028,13 +943,11 @@ class _AvlTreeIterator<V> implements BidirectionalIterator<V> { |
} |
} |
-/** |
- * Private class used to track element insertions in the [TreeSet]. |
- */ |
+/// Private class used to track element insertions in the [TreeSet]. |
class AvlNode<V> extends _TreeNode<V> { |
AvlNode<V> _left; |
AvlNode<V> _right; |
- //TODO(codefu): Remove need for [parent]; this is just an implementation note |
+ // TODO(codefu): Remove need for [parent]; this is just an implementation note |
AvlNode<V> _parent; |
int _balanceFactor = 0; |