@@ -23,8 +23,6 @@ use core::prelude::*;
23
23
// as a right child. The time complexity is the same, and re-balancing
24
24
// operations are more frequent but also cheaper.
25
25
26
- // TODO: lazy iteration, for O(n) Eq and set operations instead of O(n*log(m))
27
-
28
26
// TODO: implement Ord for TreeSet
29
27
// could be superset/subset-based or in-order lexicographic comparison... but
30
28
// there are methods for is_superset/is_subset so lexicographic is more useful
@@ -138,8 +136,43 @@ impl <K: Ord, V> TreeMap<K, V> {
138
136
if ret { self . length -= 1 }
139
137
ret
140
138
}
139
+
140
+ /// Get a lazy iterator over the nodes in the map. Requires that it
141
+ /// be frozen (immutable).
142
+ fn iter ( & self ) -> TreeMapIterator /& self <K , V > {
143
+ TreeMapIterator { stack: ~[ ] , node: & self . root }
144
+ }
145
+ }
146
+
147
+ /// Lazy forward iterator over a map
148
+ pub struct TreeMapIterator < K : Ord , V > {
149
+ priv stack : ~[ & ~TreeNode < K , V > ] ,
150
+ priv node : & Option < ~TreeNode < K , V > >
141
151
}
142
152
153
+ impl < K : Ord , V > TreeMapIterator < K , V > {
154
+ /// Advance the iterator to the next node (in order) and return a
155
+ /// tuple with a reference to the key and value. If there are no
156
+ /// more nodes, return None.
157
+ fn next ( & mut self ) -> Option < ( & self /K , & self /V ) > {
158
+ while self . stack . is_not_empty ( ) || self . node . is_some ( ) {
159
+ match * self . node {
160
+ Some ( ref x) => {
161
+ self . stack . push ( x) ;
162
+ self . node = & x. left ;
163
+ }
164
+ None => {
165
+ let res = self . stack . pop ( ) ;
166
+ self . node = & res. right ;
167
+ return Some ( ( & res. key , & res. value ) ) ;
168
+ }
169
+ }
170
+ }
171
+ None
172
+ }
173
+ }
174
+
175
+
143
176
pub struct TreeSet < T : Ord > {
144
177
priv map: TreeMap < T , ( ) >
145
178
}
@@ -611,6 +644,41 @@ mod test_treemap {
611
644
assert b. insert( 5 , 19 ) ;
612
645
assert a == b;
613
646
}
647
+
648
+ #[ test]
649
+ fn test_lazy_iterator ( ) {
650
+ let mut m = TreeMap :: new ( ) ;
651
+ let ( x1, y1) = ( 2 , 5 ) ;
652
+ let ( x2, y2) = ( 9 , 12 ) ;
653
+ let ( x3, y3) = ( 20 , -3 ) ;
654
+ let ( x4, y4) = ( 29 , 5 ) ;
655
+ let ( x5, y5) = ( 103 , 3 ) ;
656
+
657
+ assert m. insert ( x1, y1) ;
658
+ assert m. insert ( x2, y2) ;
659
+ assert m. insert ( x3, y3) ;
660
+ assert m. insert ( x4, y4) ;
661
+ assert m. insert ( x5, y5) ;
662
+
663
+ let m = m;
664
+ let mut iter = m. iter ( ) ;
665
+
666
+ // ICE:
667
+ //assert iter.next() == Some((&x1, &y1));
668
+ //assert iter.next().eq(&Some((&x1, &y1)));
669
+
670
+ assert iter. next ( ) . unwrap ( ) == ( & x1, & y1) ;
671
+ assert iter. next ( ) . unwrap ( ) == ( & x2, & y2) ;
672
+ assert iter. next ( ) . unwrap ( ) == ( & x3, & y3) ;
673
+ assert iter. next ( ) . unwrap ( ) == ( & x4, & y4) ;
674
+ assert iter. next ( ) . unwrap ( ) == ( & x5, & y5) ;
675
+
676
+ // ICE:
677
+ //assert iter.next() == None;
678
+ //assert iter.next().eq(&None);
679
+
680
+ assert iter. next ( ) . is_none ( ) ;
681
+ }
614
682
}
615
683
616
684
#[ cfg( test) ]
0 commit comments